diff options
author | Jason Gunthorpe <jgg@mellanox.com> | 2018-07-10 20:55:14 -0600 |
---|---|---|
committer | Jason Gunthorpe <jgg@mellanox.com> | 2018-07-25 14:21:21 -0600 |
commit | 1250c3048cf1632f5dbb99a0242410baff67955d (patch) | |
tree | ccf33bb417e90d4b4acd8ab1a7f674beeded6983 /include/uapi | |
parent | 3df593bfe6455f28cda879be8299b30b8601ce3b (diff) | |
download | linux-1250c3048cf1632f5dbb99a0242410baff67955d.tar.gz linux-1250c3048cf1632f5dbb99a0242410baff67955d.tar.bz2 linux-1250c3048cf1632f5dbb99a0242410baff67955d.zip |
IB/uverbs: Handle IDR and FD types without truncation
Our ABI for write() uses a s32 for FDs and a u32 for IDRs, but internally
we ended up implicitly casting these ABI values into an 'int'. For ioctl()
we use a s64 for FDs and a u64 for IDRs, again casting to an int.
The various casts to int are all missing range checks which can cause
userspace values that should be considered invalid to be accepted.
Fix this by making the generic lookup routine accept a s64, which does not
truncate the write API's u32/s32 or the ioctl API's s64. Then push the
detailed range checking down to the actual type implementations to be
shared by both interfaces.
Finally, change the copy of the uobj->id to sign extend into a s64, so eg,
if we ever wish to return a negative value for a FD it is carried
properly.
This ensures that userspace values are never weirdly interpreted due to
the various trunctations and everything that is really out of range gets
an EINVAL.
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
Diffstat (limited to 'include/uapi')
-rw-r--r-- | include/uapi/rdma/rdma_user_ioctl_cmds.h | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/include/uapi/rdma/rdma_user_ioctl_cmds.h b/include/uapi/rdma/rdma_user_ioctl_cmds.h index 1da5a1e1f3a8..24800c6c1f32 100644 --- a/include/uapi/rdma/rdma_user_ioctl_cmds.h +++ b/include/uapi/rdma/rdma_user_ioctl_cmds.h @@ -62,7 +62,12 @@ struct ib_uverbs_attr { } enum_data; __u16 reserved; } attr_data; - __aligned_u64 data; /* ptr to command, inline data or idr/fd */ + union { + /* Used by PTR_IN/OUT, ENUM_IN and IDR */ + __aligned_u64 data; + /* Used by FD_IN and FD_OUT */ + __s64 data_s64; + }; }; struct ib_uverbs_ioctl_hdr { |