infiniband: improve userspace input check
cover infiniband: improve userspace input check
Hi,
Please find a few patches against branch for-next ofgit://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband.git,
current head 3e7645800a89f2adccb8d635d36f2fb648048141.
This is a collection of patches to add more checks on userspace provided input parameters to cm, cma and verbs subsystem:
The InfiniBand/RDMA subsystems are not currently making enough checks on user input data. In particular:
- they should not read past the input buffer,
- they should not write past the output buffer.
Each of these userspace APIs should use the user provided lengths for buffers and don't read/write out of those boundaries.
I hope the proposed fixes being straightforward and not disruptive.
I've made some tests, but I cannot test every code path without a proper test suite and the matching infrastructure.
I've tested on a small InfiniBand fabric, with a 8 ports switch, one node with 2 HCAs (1 port, 2 ports), a second node with 1 HCA (1 port), each port connected to the switch. I've also tested with two node connected back to back.
I've searched for regression using the following programs:
ibaddr
ibstat
ibstatus
ibportstate <lid> query
ibroute <lid>
ibswitches
sminfo
smpquery portinfo <lid>
smpquery nodeinfo <lid>
saquery
ibv_devices
ibv_devinfo
rdma_client/rdma_server
rdma_xclient/rdma_xserver
ibv_rc_pingpong
ib_{read,write}_{bw,lat}
I've tested only with Fedora 19 using:
libipathverbs 1.2,
libmlx4 1.0.5,
libibverbs 1.1.17,
librdmacm 1.0.17,
libibmad 1.3.9,
libibumad 1.3.8,
opensm 3.3.15,
infiniband-diags 1.6.1.Testing with older/other libraries/tools could be interesting.
Please have a good review. I'm ready to anwser questions and update the patchset.
Regards.
Yann Droneaud (22):
infiniband: ib_copy_{from,to}_udata(): const'ify arguments
infiniband: ib_udata: const'ify inbuf
infiniband: ib_copy_from_udata(): check input length
infiniband: ib_copy_to_udata(): check output length
ucm: ib_ucm_event(): returns ENOSPC instead of ENOMEM
ucm: changes ib_ucm_alloc_data() src arg to be a pointer
ucm: changes ib_ucm_path_get() src arg to be a pointer
ucm: check userspace input length
ucm: use size_t for userspace buffer input and output length
ucm: ib_ucm_write(): check userspace buffer length first
ucm: ib_ucm_write(): strict userspace buffer length check
ucma: check userspace input length
ucma: ucma_migrate_id(): check output length
ucma: ucma_query_path(): check output length
ucma: use size_t for userspace buffer input and output length
ucma: ucma_write(): check userspace buffer length first
ucma: ucma_write(): strict userspace buffer length check
uverbs: check input length
uverbs: check output length
uverbs: ib_uverbs_poll_cq(): check output length against number of wc
uverbs: fix call to INIT_UDATA with no output buffer
uverbs: use size_t for userspace buffer input and output length
drivers/infiniband/core/ucm.c | 156 ++++++++++++++------ drivers/infiniband/core/ucma.c | 131 +++++++++++++---- drivers/infiniband/core/uverbs.h | 4 +- drivers/infiniband/core/uverbs_cmd.c | 258 +++++++++++++++++++++++++--------- drivers/infiniband/core/uverbs_main.c | 4 +- include/rdma/ib_verbs.h | 12 +- 6 files changed, 422 insertions(+), 143 deletions(-)
Signature · 6 lines
1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
A message that is not in the archive (sent off-list or not yet received): cover.1376847403.git.ydroneaud-RlY5vtjFyJ3QT0dZR+AlfA@public.gmane.org
PATCH 1/22 infiniband: ib_copy_{from,to}_udata(): const'ify arguments
Source buffers are not modified, let them be 'const'.
--- include/rdma/ib_verbs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
include/rdma/ib_verbs.h +2 -2
@@ -1353,12 +1353,12 @@ void *ib_get_client_data(struct ib_device *device, struct ib_client *client);void ib_set_client_data (struct ib_device *device,struct ib_client *client,void *data); -static inline int ib_copy_from_udata (void *dest,struct ib_udata *udata,size_t len) +static inline int ib_copy_from_udata (void *dest,const struct ib_udata *udata,size_t len) {return copy_from_user (dest, udata->inbuf, len) ? -EFAULT :0 ; } -static inline int ib_copy_to_udata (struct ib_udata *udata,void *src,size_t len) +static inline int ib_copy_to_udata (struct ib_udata *udata,const void *src,size_t len) {return copy_to_user (udata->outbuf, src, len) ? -EFAULT :0 ; }
Signature · 6 lines
1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 2/22 infiniband: ib_udata: const'ify inbuf
In reply to a message not in the archiveUserspace input buffer is not modified by kernel, let it be 'const'.
--- drivers/infiniband/core/uverbs_cmd.c | 2 +- include/rdma/ib_verbs.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
drivers/infiniband/core/uverbs_cmd.c +1 -1
@@ -57,7 +57,7 @@ static struct uverbs_lock_class xrcd_lock_class = { .name = "XRCD-uobj" };#define INIT_UDATA (udata, ibuf, obuf, ilen, olen) \ do { \ - (udata)->inbuf = (void __user *) (ibuf); \ + (udata)->inbuf = (const void __user *) (ibuf); \ (udata)->outbuf = (void __user *) (obuf); \ (udata)->inlen = (ilen); \ (udata)->outlen = (olen); \
include/rdma/ib_verbs.h +1 -1
@@ -974,7 +974,7 @@ struct ib_uobject { };struct ib_udata { -void __user *inbuf; +const void __user *inbuf;void __user *outbuf;size_t inlen;size_t outlen;
Signature · 6 lines
1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 3/22 infiniband: ib_copy_from_udata(): check input length
In reply to a message not in the archiveThis patch makes ib_copy_from_udata() check the input length before reading from userspace buffer to prevent out of bound access.
--- include/rdma/ib_verbs.h | 3 +++ 1 file changed, 3 insertions(+)
include/rdma/ib_verbs.h +3 -0
@@ -1355,6 +1355,9 @@ void ib_set_client_data(struct ib_device *device, struct ib_client *client,static inline int ib_copy_from_udata (void *dest,const struct ib_udata *udata,size_t len) { +if (udata->inlen < len) { +return -EINVAL ; + }return copy_from_user (dest, udata->inbuf, len) ? -EFAULT :0 ; }
Signature · 6 lines
1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 4/22 infiniband: ib_copy_to_udata(): check output length
In reply to a message not in the archiveThis patch makes ib_copy_to_udata() check the output length before writing to userspace buffer to prevent out of bound access.
--- include/rdma/ib_verbs.h | 3 +++ 1 file changed, 3 insertions(+)
include/rdma/ib_verbs.h +3 -0
@@ -1363,6 +1363,9 @@ static inline int ib_copy_from_udata(void *dest, const struct ib_udata *udata, sstatic inline int ib_copy_to_udata (struct ib_udata *udata,const void *src,size_t len) { +if (udata->outlen < len) { +return -ENOSPC ; + }return copy_to_user (udata->outbuf, src, len) ? -EFAULT :0 ; }
Signature · 6 lines
1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 5/22 ucm: ib_ucm_event(): returns ENOSPC instead of ENOMEM
In reply to a message not in the archiveWhen output buffer is too small, others infiniband functions returns ENOSPC.
This patch changes ib_ucm_event() to returns ENOSPC just like others functions.
--- drivers/infiniband/core/ucm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/infiniband/core/ucm.c +2 -2
@@ -432,7 +432,7 @@ static ssize_t ib_ucm_event(struct ib_ucm_file *file,if (uevent->data) {if (cmd.data_len < uevent->data_len) { - result = -ENOMEM ; + result = -ENOSPC ; goto done; } if (copy_to_user((void __user *)(unsigned long)cmd.data,
@@ -444,7 +444,7 @@ static ssize_t ib_ucm_event(struct ib_ucm_file *file,if (uevent->info) {if (cmd.info_len < uevent->info_len) { - result = -ENOMEM ; + result = -ENOSPC ; goto done; } if (copy_to_user((void __user *)(unsigned long)cmd.info,
Signature · 6 lines
1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 6/22 ucm: changes ib_ucm_alloc_data() src arg to be a pointer
In reply to a message not in the archiveib_icm_alloc_data() is a function to allocate a buffer to copy a userspace provided buffer.
This patch makes 'src' argument to be an explicit pointer to userspace buffer, so that static analysis won't get fooled by 'src' being currently an integer without annotation.
--- drivers/infiniband/core/ucm.c | 43 +++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-)
drivers/infiniband/core/ucm.c +31 -12
@@ -685,7 +685,7 @@ static ssize_t ib_ucm_notify(struct ib_ucm_file *file,return result; } -static int ib_ucm_alloc_data (const void **dest,u64 src,u32 len) +static int ib_ucm_alloc_data (const void **dest,const void __user *src,u32 len) {void *data;
@@ -694,7 +694,7 @@ static int ib_ucm_alloc_data(const void **dest, u64 src, u32 len)if (!len)return 0 ; - data =memdup_user ((void __user *)(unsigned long )src, len); + data =memdup_user (src, len);if (IS_ERR (data))return PTR_ERR (data);
@@ -744,7 +744,9 @@ static ssize_t ib_ucm_send_req(struct ib_ucm_file *file,if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ; - result =ib_ucm_alloc_data (¶m.private_data, cmd.data, cmd.len); + result =ib_ucm_alloc_data (¶m.private_data, + (const void __user *)(unsigned long )cmd.data, + cmd.len);if (result) goto done;
@@ -800,7 +802,9 @@ static ssize_t ib_ucm_send_rep(struct ib_ucm_file *file,if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ; - result =ib_ucm_alloc_data (¶m.private_data, cmd.data, cmd.len); + result =ib_ucm_alloc_data (¶m.private_data, + (const void __user *)(unsigned long )cmd.data, + cmd.len);if (result)return result;
@@ -840,7 +844,9 @@ static ssize_t ib_ucm_send_private_data(struct ib_ucm_file *file,if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ; - result =ib_ucm_alloc_data (&private_data, cmd.data, cmd.len); + result =ib_ucm_alloc_data (&private_data, + (const void __user *)(unsigned long )cmd.data, + cmd.len);if (result)return result;
@@ -894,11 +900,15 @@ static ssize_t ib_ucm_send_info(struct ib_ucm_file *file,if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ; - result =ib_ucm_alloc_data (&data, cmd.data, cmd.data_len); + result =ib_ucm_alloc_data (&data, + (const void __user *)(unsigned long )cmd.data, + cmd.data_len);if (result) goto done; - result =ib_ucm_alloc_data (&info, cmd.info, cmd.info_len); + result =ib_ucm_alloc_data (&info, + (const void __user *)(unsigned long )cmd.info, + cmd.info_len);if (result) goto done;
@@ -942,7 +952,9 @@ static ssize_t ib_ucm_send_mra(struct ib_ucm_file *file,if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ; - result =ib_ucm_alloc_data (&data, cmd.data, cmd.len); + result =ib_ucm_alloc_data (&data, + (const void __user *)(unsigned long )cmd.data, + cmd.len);if (result)return result;
@@ -970,7 +982,9 @@ static ssize_t ib_ucm_send_lap(struct ib_ucm_file *file,if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ; - result =ib_ucm_alloc_data (&data, cmd.data, cmd.len); + result =ib_ucm_alloc_data (&data, + (const void __user *)(unsigned long )cmd.data, + cmd.len);if (result) goto done;
@@ -1006,7 +1020,9 @@ static ssize_t ib_ucm_send_sidr_req(struct ib_ucm_file *file,if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ; - result =ib_ucm_alloc_data (¶m.private_data, cmd.data, cmd.len); + result =ib_ucm_alloc_data (¶m.private_data, + (const void __user *)(unsigned long )cmd.data, + cmd.len);if (result) goto done;
@@ -1047,11 +1063,14 @@ static ssize_t ib_ucm_send_sidr_rep(struct ib_ucm_file *file,return -EFAULT ; result =ib_ucm_alloc_data (¶m.private_data, - cmd.data, cmd.data_len); + (void __user *)(unsigned long )cmd.data, + cmd.data_len);if (result) goto done; - result =ib_ucm_alloc_data (¶m.info, cmd.info, cmd.info_len); + result =ib_ucm_alloc_data (¶m.info, + (void __user *)(unsigned long )cmd.info, + cmd.info_len);if (result) goto done;
Signature · 6 lines
1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 7/22 ucm: changes ib_ucm_path_get() src arg to be a pointer
In reply to a message not in the archiveib_icm_path_get() is a function that read data from userspace buffer. This patch makes 'src' argument to be an explicit pointer to userspace buffer, so that static analysis won't get fooled by 'src' being currently an integer without annotation.
--- drivers/infiniband/core/ucm.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-)
drivers/infiniband/core/ucm.c +10 -7
@@ -702,7 +702,7 @@ static int ib_ucm_alloc_data(const void **dest, const void __user *src, u32 len)return 0 ; } -static int ib_ucm_path_get (struct ib_sa_path_rec **path,u64 src) +static int ib_ucm_path_get (struct ib_sa_path_rec **path,const void __user *src) {struct ib_user_path_rec upath;struct ib_sa_path_rec *sa_path;
@@ -716,8 +716,7 @@ static int ib_ucm_path_get(struct ib_sa_path_rec **path, u64 src)if (!sa_path)return -ENOMEM ; -if (copy_from_user (&upath, (void __user *)(unsigned long )src, -sizeof (upath))) { +if (copy_from_user (&upath, src,sizeof (upath))) {kfree (sa_path);return -EFAULT ;
@@ -750,11 +749,13 @@ static ssize_t ib_ucm_send_req(struct ib_ucm_file *file,if (result) goto done; - result =ib_ucm_path_get (¶m.primary_path, cmd.primary_path); + result =ib_ucm_path_get (¶m.primary_path, + (const void __user *)(unsigned long )cmd.primary_path);if (result) goto done; - result =ib_ucm_path_get (¶m.alternate_path, cmd.alternate_path); + result =ib_ucm_path_get (¶m.alternate_path, + (const void __user *)(unsigned long )cmd.alternate_path);if (result) goto done;
@@ -988,7 +989,8 @@ static ssize_t ib_ucm_send_lap(struct ib_ucm_file *file,if (result) goto done; - result =ib_ucm_path_get (&path, cmd.path); + result =ib_ucm_path_get (&path, + (const void __user *)(unsigned long )cmd.path);if (result) goto done;
@@ -1026,7 +1028,8 @@ static ssize_t ib_ucm_send_sidr_req(struct ib_ucm_file *file,if (result) goto done; - result =ib_ucm_path_get (¶m.path, cmd.path); + result =ib_ucm_path_get (¶m.path, + (const void __user *)(unsigned long )cmd.path);if (result) goto done;
Signature · 6 lines
1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 8/22 ucm: check userspace input length
In reply to a message not in the archiveMakes ucm functions check the length of the input buffer before reading the command content: this will detect truncated command and will prevent ucm from reading past userspace provided buffer.
--- drivers/infiniband/core/ucm.c | 45 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+)
drivers/infiniband/core/ucm.c +45 -0
@@ -390,6 +390,9 @@ static ssize_t ib_ucm_event(struct ib_ucm_file *file,struct ib_ucm_event *uevent;int result =0 ; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (out_len <sizeof (struct ib_ucm_event_resp ))return -ENOSPC ;
@@ -475,6 +478,9 @@ static ssize_t ib_ucm_create_id(struct ib_ucm_file *file,struct ib_ucm_context *ctx;int result; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (out_len <sizeof (resp))return -ENOSPC ;
@@ -522,6 +528,9 @@ static ssize_t ib_ucm_destroy_id(struct ib_ucm_file *file,struct ib_ucm_context *ctx;int result =0 ; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (out_len <sizeof (resp))return -ENOSPC ;
@@ -567,6 +576,9 @@ static ssize_t ib_ucm_attr_id(struct ib_ucm_file *file,struct ib_ucm_context *ctx;int result =0 ; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (out_len <sizeof (resp))return -ENOSPC ;
@@ -600,6 +612,9 @@ static ssize_t ib_ucm_init_qp_attr(struct ib_ucm_file *file,struct ib_qp_attr qp_attr;int result =0 ; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (out_len <sizeof (resp))return -ENOSPC ;
@@ -647,6 +662,9 @@ static ssize_t ib_ucm_listen(struct ib_ucm_file *file,struct ib_ucm_context *ctx;int result; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ;
@@ -673,6 +691,9 @@ static ssize_t ib_ucm_notify(struct ib_ucm_file *file,struct ib_ucm_context *ctx;int result; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ;
@@ -740,6 +761,9 @@ static ssize_t ib_ucm_send_req(struct ib_ucm_file *file, param.primary_path =NULL ; param.alternate_path =NULL ; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ;
@@ -800,6 +824,9 @@ static ssize_t ib_ucm_send_rep(struct ib_ucm_file *file, param.private_data =NULL ; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ;
@@ -842,6 +869,9 @@ static ssize_t ib_ucm_send_private_data(struct ib_ucm_file *file,const void *private_data =NULL ;int result; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ;
@@ -898,6 +928,9 @@ static ssize_t ib_ucm_send_info(struct ib_ucm_file *file,const void *info =NULL ;int result; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ;
@@ -950,6 +983,9 @@ static ssize_t ib_ucm_send_mra(struct ib_ucm_file *file,const void *data =NULL ;int result; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ;
@@ -980,6 +1016,9 @@ static ssize_t ib_ucm_send_lap(struct ib_ucm_file *file,const void *data =NULL ;int result; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ;
@@ -1019,6 +1058,9 @@ static ssize_t ib_ucm_send_sidr_req(struct ib_ucm_file *file, param.private_data =NULL ; param.path =NULL ; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ;
@@ -1062,6 +1104,9 @@ static ssize_t ib_ucm_send_sidr_rep(struct ib_ucm_file *file, param.info =NULL ; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ;
Signature · 6 lines
1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 9/22 ucm: use size_t for userspace buffer input and output length
In reply to a message not in the archiveThere's no reason to use a signed type for userspace buffer length.
--- drivers/infiniband/core/ucm.c | 45 ++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 22 deletions(-)
drivers/infiniband/core/ucm.c +23 -22
@@ -383,7 +383,7 @@ err1:static ssize_t ib_ucm_event (struct ib_ucm_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct ib_ucm_context *ctx;struct ib_ucm_event_get cmd;
@@ -471,7 +471,7 @@ done:static ssize_t ib_ucm_create_id (struct ib_ucm_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct ib_ucm_create_id cmd;struct ib_ucm_create_id_resp resp;
@@ -521,7 +521,7 @@ err1:static ssize_t ib_ucm_destroy_id (struct ib_ucm_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct ib_ucm_destroy_id cmd;struct ib_ucm_destroy_id_resp resp;
@@ -569,7 +569,7 @@ static ssize_t ib_ucm_destroy_id(struct ib_ucm_file *file,static ssize_t ib_ucm_attr_id (struct ib_ucm_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct ib_ucm_attr_id_resp resp;struct ib_ucm_attr_id cmd;
@@ -604,7 +604,7 @@ static ssize_t ib_ucm_attr_id(struct ib_ucm_file *file,static ssize_t ib_ucm_init_qp_attr (struct ib_ucm_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct ib_uverbs_qp_attr resp;struct ib_ucm_init_qp_attr cmd;
@@ -656,7 +656,7 @@ static int ucm_validate_listen(__be64 service_id, __be64 service_mask)static ssize_t ib_ucm_listen (struct ib_ucm_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct ib_ucm_listen cmd;struct ib_ucm_context *ctx;
@@ -685,7 +685,7 @@ out:static ssize_t ib_ucm_notify (struct ib_ucm_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct ib_ucm_notify cmd;struct ib_ucm_context *ctx;
@@ -706,7 +706,7 @@ static ssize_t ib_ucm_notify(struct ib_ucm_file *file,return result; } -static int ib_ucm_alloc_data (const void **dest,const void __user *src,u32 len) +static int ib_ucm_alloc_data (const void **dest,const void __user *src,size_t len) {void *data;
@@ -750,7 +750,7 @@ static int ib_ucm_path_get(struct ib_sa_path_rec **path, const void __user *src)static ssize_t ib_ucm_send_req (struct ib_ucm_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct ib_cm_req_param param;struct ib_ucm_context *ctx;
@@ -815,7 +815,7 @@ done:static ssize_t ib_ucm_send_rep (struct ib_ucm_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct ib_cm_rep_param param;struct ib_ucm_context *ctx;
@@ -859,7 +859,7 @@ static ssize_t ib_ucm_send_rep(struct ib_ucm_file *file, }static ssize_t ib_ucm_send_private_data (struct ib_ucm_file *file, -const char __user *inbuf,int in_len, +const char __user *inbuf,size_t in_len,int (*func)(struct ib_cm_id *cm_id,const void *private_data,u8 private_data_len))
@@ -894,27 +894,27 @@ static ssize_t ib_ucm_send_private_data(struct ib_ucm_file *file,static ssize_t ib_ucm_send_rtu (struct ib_ucm_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {return ib_ucm_send_private_data (file, inbuf, in_len, ib_send_cm_rtu); }static ssize_t ib_ucm_send_dreq (struct ib_ucm_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {return ib_ucm_send_private_data (file, inbuf, in_len, ib_send_cm_dreq); }static ssize_t ib_ucm_send_drep (struct ib_ucm_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {return ib_ucm_send_private_data (file, inbuf, in_len, ib_send_cm_drep); } static ssize_t ib_ucm_send_info(struct ib_ucm_file *file, - const char __user *inbuf, int in_len, + const char __user *inbuf, size_t in_len, int (*func)(struct ib_cm_id *cm_id, int status, const void *info,
@@ -962,21 +962,21 @@ done:static ssize_t ib_ucm_send_rej (struct ib_ucm_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {return ib_ucm_send_info (file, inbuf, in_len, (void *)ib_send_cm_rej); }static ssize_t ib_ucm_send_apr (struct ib_ucm_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {return ib_ucm_send_info (file, inbuf, in_len, (void *)ib_send_cm_apr); }static ssize_t ib_ucm_send_mra (struct ib_ucm_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct ib_ucm_context *ctx;struct ib_ucm_mra cmd;
@@ -1008,7 +1008,7 @@ static ssize_t ib_ucm_send_mra(struct ib_ucm_file *file,static ssize_t ib_ucm_send_lap (struct ib_ucm_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct ib_ucm_context *ctx;struct ib_sa_path_rec *path =NULL ;
@@ -1048,7 +1048,7 @@ done:static ssize_t ib_ucm_send_sidr_req (struct ib_ucm_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct ib_cm_sidr_req_param param;struct ib_ucm_context *ctx;
@@ -1095,7 +1095,7 @@ done:static ssize_t ib_ucm_send_sidr_rep (struct ib_ucm_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct ib_cm_sidr_rep_param param;struct ib_ucm_sidr_rep cmd;
@@ -1143,7 +1143,8 @@ done:static ssize_t (*ucm_cmd_table[])(struct ib_ucm_file *file,const char __user *inbuf, -int in_len,int out_len) = { +size_t in_len, +size_t out_len) = { [IB_USER_CM_CMD_CREATE_ID ] = ib_ucm_create_id, [IB_USER_CM_CMD_DESTROY_ID ] = ib_ucm_destroy_id, [IB_USER_CM_CMD_ATTR_ID ] = ib_ucm_attr_id,
Signature · 6 lines
1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 10/22 ucm: ib_ucm_write(): check userspace buffer length first
In reply to a message not in the archiveLike uverbs, check the length parameter before the command type.
--- drivers/infiniband/core/ucm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/infiniband/core/ucm.c +2 -2
@@ -1178,10 +1178,10 @@ static ssize_t ib_ucm_write(struct file *filp, const char __user *buf,if (copy_from_user (&hdr, buf,sizeof (hdr)))return -EFAULT ; -if (hdr.cmd >=ARRAY_SIZE (ucm_cmd_table)) +if (hdr.in +sizeof (hdr) > len)return -EINVAL ; -if (hdr.in +sizeof (hdr) > len) +if (hdr.cmd >=ARRAY_SIZE (ucm_cmd_table))return -EINVAL ; result = ucm_cmd_table[hdr.cmd](file, buf + sizeof(hdr),
Signature · 6 lines
1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 11/22 ucm: ib_ucm_write(): strict userspace buffer length check
In reply to a message not in the archiveLike uverbs, strictly check the length parameter:
this prevent ucm from processing truncated buffer.
--- drivers/infiniband/core/ucm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/core/ucm.c +1 -1
@@ -1178,7 +1178,7 @@ static ssize_t ib_ucm_write(struct file *filp, const char __user *buf,if (copy_from_user (&hdr, buf,sizeof (hdr)))return -EFAULT ; -if (hdr.in +sizeof (hdr) > len) +if (hdr.in +sizeof (hdr) != len)return -EINVAL ;if (hdr.cmd >=ARRAY_SIZE (ucm_cmd_table))
Signature · 6 lines
1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 12/22 ucma: check userspace input length
In reply to a message not in the archiveMakes ucma functions check the length of the input buffer before reading the command content: this will detect truncated command and will prevent ucma from reading past userspace provided buffer.
--- drivers/infiniband/core/ucma.c | 66 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+)
drivers/infiniband/core/ucma.c +66 -0
@@ -297,6 +297,9 @@ static ssize_t ucma_get_event(struct ucma_file *file, const char __user *inbuf,struct ucma_event *uevent;int ret =0 ; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (out_len <sizeof uevent->resp)return -ENOSPC ;
@@ -374,6 +377,9 @@ static ssize_t ucma_create_id(struct ucma_file *file, const char __user *inbuf,enum ib_qp_type qp_type;int ret; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (out_len <sizeof (resp))return -ENOSPC ;
@@ -486,6 +492,9 @@ static ssize_t ucma_destroy_id(struct ucma_file *file, const char __user *inbuf,struct ucma_context *ctx;int ret =0 ; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (out_len <sizeof (resp))return -ENOSPC ;
@@ -519,6 +528,9 @@ static ssize_t ucma_bind_ip(struct ucma_file *file, const char __user *inbuf,struct ucma_context *ctx;int ret; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ;
@@ -539,6 +551,9 @@ static ssize_t ucma_bind(struct ucma_file *file, const char __user *inbuf,struct ucma_context *ctx;int ret; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ;
@@ -563,6 +578,9 @@ static ssize_t ucma_resolve_ip(struct ucma_file *file,struct ucma_context *ctx;int ret; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ;
@@ -586,6 +604,9 @@ static ssize_t ucma_resolve_addr(struct ucma_file *file,struct ucma_context *ctx;int ret; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ;
@@ -612,6 +633,9 @@ static ssize_t ucma_resolve_route(struct ucma_file *file,struct ucma_context *ctx;int ret; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ;
@@ -708,6 +732,9 @@ static ssize_t ucma_query_route(struct ucma_file *file,struct sockaddr *addr;int ret =0 ; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (out_len <sizeof (resp))return -ENOSPC ;
@@ -889,6 +916,9 @@ static ssize_t ucma_query(struct ucma_file *file,void __user *response;int ret; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ;
@@ -940,6 +970,9 @@ static ssize_t ucma_connect(struct ucma_file *file, const char __user *inbuf,struct ucma_context *ctx;int ret; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ;
@@ -963,6 +996,9 @@ static ssize_t ucma_listen(struct ucma_file *file, const char __user *inbuf,struct ucma_context *ctx;int ret; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ;
@@ -985,6 +1021,9 @@ static ssize_t ucma_accept(struct ucma_file *file, const char __user *inbuf,struct ucma_context *ctx;int ret; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ;
@@ -1013,6 +1052,9 @@ static ssize_t ucma_reject(struct ucma_file *file, const char __user *inbuf,struct ucma_context *ctx;int ret; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ;
@@ -1032,6 +1074,9 @@ static ssize_t ucma_disconnect(struct ucma_file *file, const char __user *inbuf,struct ucma_context *ctx;int ret; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ;
@@ -1054,6 +1099,9 @@ static ssize_t ucma_init_qp_attr(struct ucma_file *file,struct ib_qp_attr qp_attr;int ret; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (out_len <sizeof (resp))return -ENOSPC ;
@@ -1187,6 +1235,9 @@ static ssize_t ucma_set_option(struct ucma_file *file, const char __user *inbuf,void *optval;int ret; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ;
@@ -1217,6 +1268,9 @@ static ssize_t ucma_notify(struct ucma_file *file, const char __user *inbuf,struct ucma_context *ctx;int ret; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ;
@@ -1295,6 +1349,9 @@ static ssize_t ucma_join_ip_multicast(struct ucma_file *file,struct rdma_ucm_join_ip_mcast cmd;struct rdma_ucm_join_mcast join_cmd; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ;
@@ -1314,6 +1371,9 @@ static ssize_t ucma_join_multicast(struct ucma_file *file, {struct rdma_ucm_join_mcast cmd; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ;
@@ -1329,6 +1389,9 @@ static ssize_t ucma_leave_multicast(struct ucma_file *file,struct ucma_multicast *mc;int ret =0 ; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (out_len <sizeof (resp))return -ENOSPC ;
@@ -1412,6 +1475,9 @@ static ssize_t ucma_migrate_id(struct ucma_file *new_file,struct ucma_file *cur_file;int ret =0 ; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ;
Signature · 6 lines
1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 13/22 ucma: ucma_migrate_id(): check output length
In reply to a message not in the archiveMakes ucma_migrate_id() check the length of the output buffer:
this will prevent the function from writing past userspace provided buffer.
--- drivers/infiniband/core/ucma.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/infiniband/core/ucma.c +3 -0
@@ -1478,6 +1478,9 @@ static ssize_t ucma_migrate_id(struct ucma_file *new_file,if (in_len <sizeof (cmd))return -EINVAL ; +if (out_len <sizeof (resp)) +return -ENOSPC ; +if (copy_from_user (&cmd, inbuf,sizeof (cmd)))return -EFAULT ;
Signature · 6 lines
1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 14/22 ucma: ucma_query_path(): check output length
In reply to a message not in the archiveMakes ucma_query_path() check the length of the output buffer:
this will prevent the function from writing past userspace provided buffer.
--- drivers/infiniband/core/ucma.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/infiniband/core/ucma.c +3 -0
@@ -838,6 +838,9 @@ static ssize_t ucma_query_path(struct ucma_context *ctx,if (out_len <sizeof (*resp))return -ENOSPC ; +if ((out_len -sizeof (*resp))/sizeof (struct ib_path_rec_data ) < ctx->cm_id->route.num_paths) +return -ENOSPC ; + resp =kzalloc (out_len,GFP_KERNEL );if (!resp)return -ENOMEM ;
Signature · 6 lines
1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 15/22 ucma: use size_t for userspace buffer input and output length
In reply to a message not in the archiveThere's no reason to use a signed type for userspace buffer length.
--- drivers/infiniband/core/ucma.c | 55 +++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 27 deletions(-)
drivers/infiniband/core/ucma.c +28 -27
@@ -290,7 +290,7 @@ out: }static ssize_t ucma_get_event (struct ucma_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct ucma_context *ctx;struct rdma_ucm_get_event cmd;
@@ -369,7 +369,7 @@ static int ucma_get_qp_type(struct rdma_ucm_create_id *cmd, enum ib_qp_type *qp_ }static ssize_t ucma_create_id (struct ucma_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct rdma_ucm_create_id cmd;struct rdma_ucm_create_id_resp resp;
@@ -485,7 +485,7 @@ static int ucma_free_ctx(struct ucma_context *ctx) }static ssize_t ucma_destroy_id (struct ucma_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct rdma_ucm_destroy_id cmd;struct rdma_ucm_destroy_id_resp resp;
@@ -522,7 +522,7 @@ static ssize_t ucma_destroy_id(struct ucma_file *file, const char __user *inbuf, }static ssize_t ucma_bind_ip (struct ucma_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct rdma_ucm_bind_ip cmd;struct ucma_context *ctx;
@@ -544,7 +544,7 @@ static ssize_t ucma_bind_ip(struct ucma_file *file, const char __user *inbuf, }static ssize_t ucma_bind (struct ucma_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct rdma_ucm_bind cmd;struct sockaddr *addr;
@@ -572,7 +572,7 @@ static ssize_t ucma_bind(struct ucma_file *file, const char __user *inbuf,static ssize_t ucma_resolve_ip (struct ucma_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct rdma_ucm_resolve_ip cmd;struct ucma_context *ctx;
@@ -597,7 +597,7 @@ static ssize_t ucma_resolve_ip(struct ucma_file *file,static ssize_t ucma_resolve_addr (struct ucma_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct rdma_ucm_resolve_addr cmd;struct sockaddr *src, *dst;
@@ -627,7 +627,7 @@ static ssize_t ucma_resolve_addr(struct ucma_file *file,static ssize_t ucma_resolve_route (struct ucma_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct rdma_ucm_resolve_route cmd;struct ucma_context *ctx;
@@ -724,7 +724,7 @@ static void ucma_copy_iw_route(struct rdma_ucm_query_route_resp *resp,static ssize_t ucma_query_route (struct ucma_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct rdma_ucm_query cmd;struct rdma_ucm_query_route_resp resp;
@@ -802,7 +802,7 @@ static void ucma_query_device_addr(struct rdma_cm_id *cm_id, }static ssize_t ucma_query_addr (struct ucma_context *ctx, -void __user *response,int out_len) +void __user *response,size_t out_len) {struct rdma_ucm_query_addr_resp resp;struct sockaddr *addr;
@@ -830,7 +830,7 @@ static ssize_t ucma_query_addr(struct ucma_context *ctx, }static ssize_t ucma_query_path (struct ucma_context *ctx, -void __user *response,int out_len) +void __user *response,size_t out_len) {struct rdma_ucm_query_path_resp *resp;int i, ret =0 ;
@@ -865,7 +865,7 @@ static ssize_t ucma_query_path(struct ucma_context *ctx, }static ssize_t ucma_query_gid (struct ucma_context *ctx, -void __user *response,int out_len) +void __user *response,size_t out_len) {struct rdma_ucm_query_addr_resp resp;struct sockaddr_ib *addr;
@@ -912,7 +912,7 @@ static ssize_t ucma_query_gid(struct ucma_context *ctx,static ssize_t ucma_query (struct ucma_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct rdma_ucm_query cmd;struct ucma_context *ctx;
@@ -966,7 +966,7 @@ static void ucma_copy_conn_param(struct rdma_cm_id *id, }static ssize_t ucma_connect (struct ucma_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct rdma_ucm_connect cmd;struct rdma_conn_param conn_param;
@@ -993,7 +993,7 @@ static ssize_t ucma_connect(struct ucma_file *file, const char __user *inbuf, }static ssize_t ucma_listen (struct ucma_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct rdma_ucm_listen cmd;struct ucma_context *ctx;
@@ -1017,7 +1017,7 @@ static ssize_t ucma_listen(struct ucma_file *file, const char __user *inbuf, }static ssize_t ucma_accept (struct ucma_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct rdma_ucm_accept cmd;struct rdma_conn_param conn_param;
@@ -1049,7 +1049,7 @@ static ssize_t ucma_accept(struct ucma_file *file, const char __user *inbuf, }static ssize_t ucma_reject (struct ucma_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct rdma_ucm_reject cmd;struct ucma_context *ctx;
@@ -1071,7 +1071,7 @@ static ssize_t ucma_reject(struct ucma_file *file, const char __user *inbuf, }static ssize_t ucma_disconnect (struct ucma_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct rdma_ucm_disconnect cmd;struct ucma_context *ctx;
@@ -1094,7 +1094,7 @@ static ssize_t ucma_disconnect(struct ucma_file *file, const char __user *inbuf,static ssize_t ucma_init_qp_attr (struct ucma_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct rdma_ucm_init_qp_attr cmd;struct ib_uverbs_qp_attr resp;
@@ -1231,7 +1231,7 @@ static int ucma_set_option_level(struct ucma_context *ctx, int level, }static ssize_t ucma_set_option (struct ucma_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct rdma_ucm_set_option cmd;struct ucma_context *ctx;
@@ -1265,7 +1265,7 @@ out: }static ssize_t ucma_notify (struct ucma_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct rdma_ucm_notify cmd;struct ucma_context *ctx;
@@ -1287,7 +1287,7 @@ static ssize_t ucma_notify(struct ucma_file *file, const char __user *inbuf, }static ssize_t ucma_process_join (struct ucma_file *file, -struct rdma_ucm_join_mcast *cmd,int out_len) +struct rdma_ucm_join_mcast *cmd,size_t out_len) {struct rdma_ucm_create_id_resp resp;struct ucma_context *ctx;
@@ -1347,7 +1347,7 @@ err1:static ssize_t ucma_join_ip_multicast (struct ucma_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct rdma_ucm_join_ip_mcast cmd;struct rdma_ucm_join_mcast join_cmd;
@@ -1370,7 +1370,7 @@ static ssize_t ucma_join_ip_multicast(struct ucma_file *file,static ssize_t ucma_join_multicast (struct ucma_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct rdma_ucm_join_mcast cmd;
@@ -1385,7 +1385,7 @@ static ssize_t ucma_join_multicast(struct ucma_file *file,static ssize_t ucma_leave_multicast (struct ucma_file *file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct rdma_ucm_destroy_id cmd;struct rdma_ucm_destroy_id_resp resp;
@@ -1469,7 +1469,7 @@ static void ucma_move_events(struct ucma_context *ctx, struct ucma_file *file)static ssize_t ucma_migrate_id (struct ucma_file *new_file,const char __user *inbuf, -int in_len,int out_len) +size_t in_len,size_t out_len) {struct rdma_ucm_migrate_id cmd;struct rdma_ucm_migrate_resp resp;
@@ -1533,7 +1533,8 @@ file_put:static ssize_t (*ucma_cmd_table[])(struct ucma_file *file,const char __user *inbuf, -int in_len,int out_len) = { +size_t in_len,size_t out_len) = { + [RDMA_USER_CM_CMD_CREATE_ID ] = ucma_create_id, [RDMA_USER_CM_CMD_DESTROY_ID ] = ucma_destroy_id, [RDMA_USER_CM_CMD_BIND_IP ] = ucma_bind_ip,
Signature · 6 lines
1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 16/22 ucma: ucma_write(): check userspace buffer length first
In reply to a message not in the archiveLike uverbs, check the length parameter before the command type.
--- drivers/infiniband/core/ucma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/infiniband/core/ucma.c +2 -2
@@ -1573,10 +1573,10 @@ static ssize_t ucma_write(struct file *filp, const char __user *buf,if (copy_from_user (&hdr, buf,sizeof (hdr)))return -EFAULT ; -if (hdr.cmd >=ARRAY_SIZE (ucma_cmd_table)) +if (hdr.in +sizeof (hdr) > len)return -EINVAL ; -if (hdr.in +sizeof (hdr) > len) +if (hdr.cmd >=ARRAY_SIZE (ucma_cmd_table))return -EINVAL ;if (!ucma_cmd_table[hdr.cmd])
Signature · 6 lines
1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 17/22 ucma: ucma_write(): strict userspace buffer length check
In reply to a message not in the archiveLike uverbs, strictly check the length parameter:
this prevent ucma from processing truncated buffer.
--- drivers/infiniband/core/ucma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/core/ucma.c +1 -1
@@ -1573,7 +1573,7 @@ static ssize_t ucma_write(struct file *filp, const char __user *buf,if (copy_from_user (&hdr, buf,sizeof (hdr)))return -EFAULT ; -if (hdr.in +sizeof (hdr) > len) +if (hdr.in +sizeof (hdr) != len)return -EINVAL ;if (hdr.cmd >=ARRAY_SIZE (ucma_cmd_table))
Signature · 6 lines
1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 18/22 uverbs: check input length
In reply to a message not in the archiveMakes verbs functions check the length of the input buffer before reading the command content: this will detect truncated command and will prevent uverbs from reading past userspace provided buffer.
--- drivers/infiniband/core/uverbs_cmd.c | 102 +++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+)
drivers/infiniband/core/uverbs_cmd.c +102 -0
@@ -298,6 +298,9 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,struct file *filp;int ret; +if (in_len <sizeof cmd) +return -EINVAL ; +if (out_len <sizeof resp)return -ENOSPC ;
@@ -392,6 +395,9 @@ ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file,struct ib_device_attr attr;int ret; +if (in_len <sizeof cmd) +return -EINVAL ; +if (out_len <sizeof resp)return -ENOSPC ;
@@ -461,6 +467,9 @@ ssize_t ib_uverbs_query_port(struct ib_uverbs_file *file,struct ib_port_attr attr;int ret; +if (in_len <sizeof cmd) +return -EINVAL ; +if (out_len <sizeof resp)return -ENOSPC ;
@@ -513,6 +522,9 @@ ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file,struct ib_pd *pd;int ret; +if (in_len <sizeof cmd) +return -EINVAL ; +if (out_len <sizeof resp)return -ENOSPC ;
@@ -584,6 +596,9 @@ ssize_t ib_uverbs_dealloc_pd(struct ib_uverbs_file *file,struct ib_uobject *uobj;int ret; +if (in_len <sizeof cmd) +return -EINVAL ; +if (copy_from_user (&cmd, buf,sizeof cmd))return -EFAULT ;
@@ -710,6 +725,9 @@ ssize_t ib_uverbs_open_xrcd(struct ib_uverbs_file *file,int ret =0 ;int new_xrcd =0 ; +if (in_len <sizeof cmd) +return -EINVAL ; +if (out_len <sizeof resp)return -ENOSPC ;
@@ -845,6 +863,9 @@ ssize_t ib_uverbs_close_xrcd(struct ib_uverbs_file *file,int live;int ret =0 ; +if (in_len <sizeof cmd) +return -EINVAL ; +if (copy_from_user (&cmd, buf,sizeof cmd))return -EFAULT ;
@@ -922,6 +943,9 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file,struct ib_mr *mr;int ret; +if (in_len <sizeof cmd) +return -EINVAL ; +if (out_len <sizeof resp)return -ENOSPC ;
@@ -1020,6 +1044,9 @@ ssize_t ib_uverbs_dereg_mr(struct ib_uverbs_file *file,struct ib_uobject *uobj;int ret = -EINVAL ; +if (in_len <sizeof cmd) +return -EINVAL ; +if (copy_from_user (&cmd, buf,sizeof cmd))return -EFAULT ;
@@ -1060,6 +1087,9 @@ ssize_t ib_uverbs_alloc_mw(struct ib_uverbs_file *file,struct ib_mw *mw;int ret; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (out_len <sizeof (resp))return -ENOSPC ;
@@ -1140,6 +1170,9 @@ ssize_t ib_uverbs_dealloc_mw(struct ib_uverbs_file *file,struct ib_uobject *uobj;int ret = -EINVAL ; +if (in_len <sizeof (cmd)) +return -EINVAL ; +if (copy_from_user (&cmd, buf,sizeof (cmd)))return -EFAULT ;
@@ -1178,6 +1211,9 @@ ssize_t ib_uverbs_create_comp_channel(struct ib_uverbs_file *file,struct file *filp;int ret; +if (in_len <sizeof cmd) +return -EINVAL ; +if (out_len <sizeof resp)return -ENOSPC ;
@@ -1218,6 +1254,9 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file,struct ib_cq *cq;int ret; +if (in_len <sizeof cmd) +return -EINVAL ; +if (out_len <sizeof resp)return -ENOSPC ;
@@ -1317,6 +1356,9 @@ ssize_t ib_uverbs_resize_cq(struct ib_uverbs_file *file,struct ib_cq *cq;int ret = -EINVAL ; +if (in_len <sizeof cmd) +return -EINVAL ; +if (copy_from_user (&cmd, buf,sizeof cmd))return -EFAULT ;
@@ -1382,6 +1424,9 @@ ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file,struct ib_wc wc;int ret; +if (in_len <sizeof cmd) +return -EINVAL ; +if (copy_from_user (&cmd, buf,sizeof cmd))return -EFAULT ;
@@ -1428,6 +1473,9 @@ ssize_t ib_uverbs_req_notify_cq(struct ib_uverbs_file *file,struct ib_uverbs_req_notify_cq cmd;struct ib_cq *cq; +if (in_len <sizeof cmd) +return -EINVAL ; +if (copy_from_user (&cmd, buf,sizeof cmd))return -EFAULT ;
@@ -1455,6 +1503,9 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file,struct ib_uverbs_event_file *ev_file;int ret = -EINVAL ; +if (in_len <sizeof cmd) +return -EINVAL ; +if (copy_from_user (&cmd, buf,sizeof cmd))return -EFAULT ;
@@ -1513,6 +1564,9 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,struct ib_qp_init_attr attr;int ret; +if (in_len <sizeof cmd) +return -EINVAL ; +if (out_len <sizeof resp)return -ENOSPC ;
@@ -1703,6 +1757,9 @@ ssize_t ib_uverbs_open_qp(struct ib_uverbs_file *file,struct ib_qp_open_attr attr;int ret; +if (in_len <sizeof cmd) +return -EINVAL ; +if (out_len <sizeof resp)return -ENOSPC ;
@@ -1795,6 +1852,9 @@ ssize_t ib_uverbs_query_qp(struct ib_uverbs_file *file,struct ib_qp_init_attr *init_attr;int ret; +if (in_len <sizeof cmd) +return -EINVAL ; +if (copy_from_user (&cmd, buf,sizeof cmd))return -EFAULT ;
@@ -1908,6 +1968,9 @@ ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,struct ib_qp_attr *attr;int ret; +if (in_len <sizeof cmd) +return -EINVAL ; +if (copy_from_user (&cmd, buf,sizeof cmd))return -EFAULT ;
@@ -2001,6 +2064,9 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file,struct ib_uqp_object *obj;int ret = -EINVAL ; +if (in_len <sizeof cmd) +return -EINVAL ; +if (copy_from_user (&cmd, buf,sizeof cmd))return -EFAULT ;
@@ -2061,6 +2127,9 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,int is_ud;ssize_t ret = -EINVAL ; +if (in_len <sizeof cmd) +return -EINVAL ; +if (copy_from_user (&cmd, buf,sizeof cmd))return -EFAULT ;
@@ -2299,6 +2368,9 @@ ssize_t ib_uverbs_post_recv(struct ib_uverbs_file *file,struct ib_qp *qp;ssize_t ret = -EINVAL ; +if (in_len <sizeof cmd) +return -EINVAL ; +if (copy_from_user (&cmd, buf,sizeof cmd))return -EFAULT ;
@@ -2348,6 +2420,9 @@ ssize_t ib_uverbs_post_srq_recv(struct ib_uverbs_file *file,struct ib_srq *srq;ssize_t ret = -EINVAL ; +if (in_len <sizeof cmd) +return -EINVAL ; +if (copy_from_user (&cmd, buf,sizeof cmd))return -EFAULT ;
@@ -2399,6 +2474,9 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file,struct ib_ah_attr attr;int ret; +if (in_len <sizeof cmd) +return -EINVAL ; +if (out_len <sizeof resp)return -ENOSPC ;
@@ -2485,6 +2563,9 @@ ssize_t ib_uverbs_destroy_ah(struct ib_uverbs_file *file,struct ib_uobject *uobj;int ret; +if (in_len <sizeof cmd) +return -EINVAL ; +if (copy_from_user (&cmd, buf,sizeof cmd))return -EFAULT ;
@@ -2523,6 +2604,9 @@ ssize_t ib_uverbs_attach_mcast(struct ib_uverbs_file *file,struct ib_uverbs_mcast_entry *mcast;int ret; +if (in_len <sizeof cmd) +return -EINVAL ; +if (copy_from_user (&cmd, buf,sizeof cmd))return -EFAULT ;
@@ -2570,6 +2654,9 @@ ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file,struct ib_uverbs_mcast_entry *mcast;int ret = -EINVAL ; +if (in_len <sizeof cmd) +return -EINVAL ; +if (copy_from_user (&cmd, buf,sizeof cmd))return -EFAULT ;
@@ -2740,6 +2827,9 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file,struct ib_udata udata;int ret; +if (in_len <sizeof cmd) +return -EINVAL ; +if (out_len <sizeof resp)return -ENOSPC ;
@@ -2773,6 +2863,9 @@ ssize_t ib_uverbs_create_xsrq(struct ib_uverbs_file *file,struct ib_udata udata;int ret; +if (in_len <sizeof cmd) +return -EINVAL ; +if (out_len <sizeof resp)return -ENOSPC ;
@@ -2800,6 +2893,9 @@ ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file,struct ib_srq_attr attr;int ret; +if (in_len <sizeof cmd) +return -EINVAL ; +if (copy_from_user (&cmd, buf,sizeof cmd))return -EFAULT ;
@@ -2830,6 +2926,9 @@ ssize_t ib_uverbs_query_srq(struct ib_uverbs_file *file,struct ib_srq *srq;int ret; +if (in_len <sizeof cmd) +return -EINVAL ; +if (out_len <sizeof resp)return -ENOSPC ;
@@ -2873,6 +2972,9 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file,struct ib_usrq_object *us;enum ib_srq_type srq_type; +if (in_len <sizeof cmd) +return -EINVAL ; +if (copy_from_user (&cmd, buf,sizeof cmd))return -EFAULT ;
Signature · 6 lines
1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 19/22 uverbs: check output length
In reply to a message not in the archiveMakes uverbs functions check the length of the output buffer:
this will prevent uverbs from writing past userspace provided buffer.
--- drivers/infiniband/core/uverbs_cmd.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)
drivers/infiniband/core/uverbs_cmd.c +27 -0
@@ -1359,6 +1359,9 @@ ssize_t ib_uverbs_resize_cq(struct ib_uverbs_file *file,if (in_len <sizeof cmd)return -EINVAL ; +if (out_len <sizeof resp) +return -ENOSPC ; +if (copy_from_user (&cmd, buf,sizeof cmd))return -EFAULT ;
@@ -1427,6 +1430,9 @@ ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file,if (in_len <sizeof cmd)return -EINVAL ; +if (out_len <sizeof resp) +return -ENOSPC ; +if (copy_from_user (&cmd, buf,sizeof cmd))return -EFAULT ;
@@ -1506,6 +1512,9 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file,if (in_len <sizeof cmd)return -EINVAL ; +if (out_len <sizeof resp) +return -ENOSPC ; +if (copy_from_user (&cmd, buf,sizeof cmd))return -EFAULT ;
@@ -1855,6 +1864,9 @@ ssize_t ib_uverbs_query_qp(struct ib_uverbs_file *file,if (in_len <sizeof cmd)return -EINVAL ; +if (out_len <sizeof resp) +return -ENOSPC ; +if (copy_from_user (&cmd, buf,sizeof cmd))return -EFAULT ;
@@ -2067,6 +2079,9 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file,if (in_len <sizeof cmd)return -EINVAL ; +if (out_len <sizeof resp) +return -ENOSPC ; +if (copy_from_user (&cmd, buf,sizeof cmd))return -EFAULT ;
@@ -2130,6 +2145,9 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,if (in_len <sizeof cmd)return -EINVAL ; +if (out_len <sizeof resp) +return -ENOSPC ; +if (copy_from_user (&cmd, buf,sizeof cmd))return -EFAULT ;
@@ -2371,6 +2389,9 @@ ssize_t ib_uverbs_post_recv(struct ib_uverbs_file *file,if (in_len <sizeof cmd)return -EINVAL ; +if (out_len <sizeof resp) +return -ENOSPC ; +if (copy_from_user (&cmd, buf,sizeof cmd))return -EFAULT ;
@@ -2423,6 +2444,9 @@ ssize_t ib_uverbs_post_srq_recv(struct ib_uverbs_file *file,if (in_len <sizeof cmd)return -EINVAL ; +if (out_len <sizeof resp) +return -ENOSPC ; +if (copy_from_user (&cmd, buf,sizeof cmd))return -EFAULT ;
@@ -2975,6 +2999,9 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file,if (in_len <sizeof cmd)return -EINVAL ; +if (out_len <sizeof resp) +return -ENOSPC ; +if (copy_from_user (&cmd, buf,sizeof cmd))return -EFAULT ;
Signature · 6 lines
1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 20/22 uverbs: ib_uverbs_poll_cq(): check output length against number of wc
In reply to a message not in the archiveMakes ib_uverbs_poll_cq() check the length of the output buffer:
this will prevent the function from writing past userspace provided buffer.
--- drivers/infiniband/core/uverbs_cmd.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/infiniband/core/uverbs_cmd.c +3 -0
@@ -1436,6 +1436,9 @@ ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file,if (copy_from_user (&cmd, buf,sizeof cmd))return -EFAULT ; +if ((out_len -sizeof resp)/(sizeof (struct ib_uverbs_wc )) < cmd.ne) +return -ENOSPC ; + cq =idr_read_cq (cmd.cq_handle, file->ucontext,0 );if (!cq)return -EINVAL ;
Signature · 6 lines
1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 21/22 uverbs: fix call to INIT_UDATA with no output buffer
In reply to a message not in the archiveWhen using INIT_UDATA() with an output buffer set to NULL, there's no space available, so output buffer length should be set to 0.
--- drivers/infiniband/core/uverbs_cmd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/infiniband/core/uverbs_cmd.c +2 -2
@@ -1990,7 +1990,7 @@ ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,return -EFAULT ;INIT_UDATA (&udata, buf +sizeof cmd,NULL , in_len -sizeof cmd, - out_len); +0 ); attr =kmalloc (sizeof *attr,GFP_KERNEL );if (!attr)
@@ -2927,7 +2927,7 @@ ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file,return -EFAULT ;INIT_UDATA (&udata, buf +sizeof cmd,NULL , in_len -sizeof cmd, - out_len); +0 ); srq =idr_read_srq (cmd.srq_handle, file->ucontext);if (!srq)
Signature · 6 lines
1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 22/22 uverbs: use size_t for userspace buffer input and output length
In reply to a message not in the archiveThere's no reason to use a signed type for userspace buffer length.
--- drivers/infiniband/core/uverbs.h | 4 +- drivers/infiniband/core/uverbs_cmd.c | 120 +++++++++++++++++----------------- drivers/infiniband/core/uverbs_main.c | 4 +- 3 files changed, 64 insertions(+), 64 deletions(-)
drivers/infiniband/core/uverbs.h +2 -2
@@ -179,8 +179,8 @@ void ib_uverbs_dealloc_xrcd(struct ib_uverbs_device *dev, struct ib_xrcd *xrcd);#define IB_UVERBS_DECLARE_CMD (name) \ ssize_t ib_uverbs_##name(struct ib_uverbs_file *file, \ - const char __user *buf, int in_len, \ - int out_len) + const char __user *buf, size_t in_len, \ + size_t out_len)IB_UVERBS_DECLARE_CMD (get_context);IB_UVERBS_DECLARE_CMD (query_device);
drivers/infiniband/core/uverbs_cmd.c +60 -60
330 lines not on this page · raw message
drivers/infiniband/core/uverbs_main.c +2 -2
@@ -78,8 +78,8 @@ static DEFINE_SPINLOCK(map_lock); static DECLARE_BITMAP(dev_map, IB_UVERBS_MAX_DEVICES);static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file, -const char __user *buf,int in_len, -int out_len) = { +const char __user *buf,size_t in_len, +size_t out_len) = { [IB_USER_VERBS_CMD_GET_CONTEXT ] = ib_uverbs_get_context, [IB_USER_VERBS_CMD_QUERY_DEVICE ] = ib_uverbs_query_device, [IB_USER_VERBS_CMD_QUERY_PORT ] = ib_uverbs_query_port,
Signature · 6 lines
1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html