Remove stack ib_udata's
Subsystems (17)
Jason Gunthorpe
maintainercover Remove stack ib_udata's
Sashiko pointed out these are dangerous, and the create_qp() one is in fact a bug. The query_device is just ugly old code.
Remove the stack ib_udata's from both places.
Jason Gunthorpe (2):
RDMA/core: Don't make a dummy ib_udata on the stack in create_qp
RDMA: Update the query_device() op
drivers/infiniband/core/core_priv.h | 2 +- drivers/infiniband/core/device.c | 3 +-- drivers/infiniband/core/ib_core_uverbs.c | 12 +++++++++++ drivers/infiniband/core/rdma_core.h | 7 +++++++ drivers/infiniband/core/uverbs_cmd.c | 14 +------------ drivers/infiniband/core/uverbs_std_types_qp.c | 3 +-- drivers/infiniband/core/verbs.c | 20 ++++++++++--------- drivers/infiniband/hw/bnxt_re/ib_verbs.c | 5 ++++- drivers/infiniband/hw/cxgb4/provider.c | 8 +++++--- drivers/infiniband/hw/erdma/erdma_verbs.c | 9 +++++++-- drivers/infiniband/hw/hns/hns_roce_main.c | 7 ++++++- drivers/infiniband/hw/ionic/ionic_ibdev.c | 7 ++++++- drivers/infiniband/hw/irdma/verbs.c | 8 +++++--- drivers/infiniband/hw/mana/main.c | 7 ++++++- drivers/infiniband/hw/mlx4/main.c | 13 ++++++------ drivers/infiniband/hw/mthca/mthca_provider.c | 13 +++++++----- drivers/infiniband/hw/ocrdma/ocrdma_verbs.c | 8 +++++--- drivers/infiniband/hw/qedr/verbs.c | 7 ++++++- drivers/infiniband/hw/usnic/usnic_ib_verbs.c | 8 +++++--- .../infiniband/hw/vmw_pvrdma/pvrdma_verbs.c | 8 +++++--- drivers/infiniband/sw/rdmavt/vt.c | 9 ++++++--- drivers/infiniband/sw/rxe/rxe_verbs.c | 14 ++++--------- drivers/infiniband/sw/siw/siw_verbs.c | 8 +++++--- 23 files changed, 124 insertions(+), 76 deletions(-)
base-commit: fd9482545e37fb6b7e04b588ad2bd80a2779776c
Signature · 1 line
2.43.0
Jason Gunthorpe
maintainerPATCH 1/2 RDMA/core: Don't make a dummy ib_udata on the stack in create_qp
Sashiko points out the udata for destruction has to be created using uverbs_get_cleared_udata(). Move it to ib_core_uverbs.c so that the core qp code can call it. Rework the call chain to pass the struct uverbs_attr_bundle right up to the driver op callback.
Fixes a possible wild stack reference in drivers during error unwinding, mlx5 can call rdma_udata_to_drv_context() from destroy_qp() when destroying a QP.
--- drivers/infiniband/core/core_priv.h | 2 +- drivers/infiniband/core/ib_core_uverbs.c | 12 +++++++++++ drivers/infiniband/core/rdma_core.h | 7 +++++++ drivers/infiniband/core/uverbs_cmd.c | 14 +------------ drivers/infiniband/core/uverbs_std_types_qp.c | 3 +-- drivers/infiniband/core/verbs.c | 20 ++++++++++--------- 6 files changed, 33 insertions(+), 25 deletions(-)
drivers/infiniband/core/core_priv.h +1 -1
@@ -321,7 +321,7 @@ void nldev_exit(void);struct ib_qp *ib_create_qp_user (struct ib_device *dev,struct ib_pd *pd,struct ib_qp_init_attr *attr, -struct ib_udata *udata, +struct uverbs_attr_bundle *uattrs,struct ib_uqp_object *uobj,const char *caller);void ib_qp_usecnt_inc (struct ib_qp *qp);
drivers/infiniband/core/ib_core_uverbs.c +12 -0
@@ -532,6 +532,18 @@ int uverbs_destroy_def_handler(struct uverbs_attr_bundle *attrs) }EXPORT_SYMBOL (uverbs_destroy_def_handler); +/* +* When calling a destroy function during an error unwind we need to pass in +* the udata that is sanitized of all user arguments. Ie from the driver +* perspective it looks like no udata was passed. +*/ +struct ib_udata *uverbs_get_cleared_udata (struct uverbs_attr_bundle *attrs) +{ + attrs->driver_udata = (struct ib_udata ){}; +return &attrs->driver_udata; +} +EXPORT_SYMBOL_NS_GPL (uverbs_get_cleared_udata,"rdma_core" ); +/** * _uverbs_alloc() - Quickly allocate memory for use with a bundle * @bundle: The bundle
drivers/infiniband/core/rdma_core.h +7 -0
@@ -71,7 +71,14 @@ int uverbs_output_written(const struct uverbs_attr_bundle *bundle, size_t idx);void setup_ufile_idr_uobject (struct ib_uverbs_file *ufile); +#if IS_ENABLED (CONFIG_INFINIBAND_USER_ACCESS )struct ib_udata *uverbs_get_cleared_udata (struct uverbs_attr_bundle *attrs); +#else +static inline struct ib_udata *uverbs_get_cleared_udata (struct uverbs_attr_bundle *attrs) +{ +return NULL ; +} +#endif /* * This is the runtime description of the uverbs API, used by the syscall
drivers/infiniband/core/uverbs_cmd.c +1 -13
@@ -163,17 +163,6 @@ static int uverbs_request_finish(struct uverbs_req_iter *iter)return 0 ; } -/* -* When calling a destroy function during an error unwind we need to pass in -* the udata that is sanitized of all user arguments. Ie from the driver -* perspective it looks like no udata was passed. -*/ -struct ib_udata *uverbs_get_cleared_udata (struct uverbs_attr_bundle *attrs) -{ - attrs->driver_udata = (struct ib_udata ){}; -return &attrs->driver_udata; -} -static struct ib_uverbs_completion_event_file *_ib_uverbs_lookup_comp_file (s32 fd,struct uverbs_attr_bundle *attrs) {
@@ -1462,8 +1451,7 @@ static int create_qp(struct uverbs_attr_bundle *attrs, attr.source_qpn = cmd->source_qpn; } - qp =ib_create_qp_user (device, pd, &attr, &attrs->driver_udata, obj, -KBUILD_MODNAME ); + qp =ib_create_qp_user (device, pd, &attr, attrs, obj,KBUILD_MODNAME );if (IS_ERR (qp)) { ret =PTR_ERR (qp); goto err_put;
drivers/infiniband/core/uverbs_std_types_qp.c +1 -2
@@ -248,8 +248,7 @@ static int UVERBS_HANDLER(UVERBS_METHOD_QP_CREATE)(set_caps (&attr, &cap, true);mutex_init (&obj->mcast_lock); - qp =ib_create_qp_user (device, pd, &attr, &attrs->driver_udata, obj, -KBUILD_MODNAME ); + qp =ib_create_qp_user (device, pd, &attr, attrs, obj,KBUILD_MODNAME );if (IS_ERR (qp)) { ret =PTR_ERR (qp); goto err_put;
drivers/infiniband/core/verbs.c +11 -9
@@ -53,6 +53,7 @@#include <rdma/rw.h> #include <rdma/lag.h> +#include "rdma_core.h" #include "core_priv.h" #include <trace/events/rdma_core.h>
@@ -1265,10 +1266,9 @@ static struct ib_qp *create_xrc_qp_user(struct ib_qp *qp,static struct ib_qp *create_qp (struct ib_device *dev,struct ib_pd *pd,struct ib_qp_init_attr *attr, -struct ib_udata *udata, +struct uverbs_attr_bundle *uattrs,struct ib_uqp_object *uobj,const char *caller) { -struct ib_udata dummy = {};struct ib_qp *qp;int ret;
@@ -1301,9 +1301,10 @@ static struct ib_qp *create_qp(struct ib_device *dev, struct ib_pd *pd, qp->recv_cq = attr->recv_cq;rdma_restrack_new (&qp->res,RDMA_RESTRACK_QP ); -WARN_ONCE (!udata && !caller,"Missing kernel QP owner" ); -rdma_restrack_set_name (&qp->res, udata ?NULL : caller); - ret = dev->ops.create_qp (qp, attr, udata); +WARN_ONCE (!uattrs && !caller,"Missing kernel QP owner" ); +rdma_restrack_set_name (&qp->res, uattrs ?NULL : caller); + ret = dev->ops.create_qp (qp, attr, + uattrs ? &uattrs->driver_udata :NULL );if (ret) goto err_create;
@@ -1322,7 +1323,8 @@ static struct ib_qp *create_qp(struct ib_device *dev, struct ib_pd *pd,return qp; err_security: - qp->device->ops.destroy_qp (qp, udata ? &dummy :NULL ); + qp->device->ops.destroy_qp ( + qp, uattrs ?uverbs_get_cleared_udata (uattrs) :NULL ); err_create:rdma_restrack_put (&qp->res);kfree (qp);
@@ -1338,13 +1340,13 @@ static struct ib_qp *create_qp(struct ib_device *dev, struct ib_pd *pd,* @attr: A list of initial attributes required to create the * QP. If QP creation succeeds, then the attributes are updated to * the actual capabilities of the created QP. -* @udata: User data +* @uattrs: User ioctl attributes and udata * @uobj: uverbs obect * @caller: caller's build-time module name */ struct ib_qp *ib_create_qp_user (struct ib_device *dev,struct ib_pd *pd,struct ib_qp_init_attr *attr, -struct ib_udata *udata, +struct uverbs_attr_bundle *uattrs,struct ib_uqp_object *uobj,const char *caller) {struct ib_qp *qp, *xrc_qp;
@@ -1352,7 +1354,7 @@ struct ib_qp *ib_create_qp_user(struct ib_device *dev, struct ib_pd *pd,if (attr->qp_type ==IB_QPT_XRC_TGT ) qp =create_qp (dev, pd, attr,NULL ,NULL , caller);else - qp =create_qp (dev, pd, attr, udata, uobj,NULL ); + qp =create_qp (dev, pd, attr, uattrs, uobj,NULL );if (attr->qp_type !=IB_QPT_XRC_TGT ||IS_ERR (qp))return qp;
Signature · 1 line
2.43.0
Jason Gunthorpe
maintainerPATCH 2/2 RDMA: Update the query_device() op
In reply to Jason GunthorpeThis op hasn't followed the normal pattern of passing NULL for udata when invoked by the kernel. Instead the kernel caller creates a dummy ib_udata on the stack and passes that in. It does not seem to currently be a bug, but this flow should be modernized to use the new API flow and in the process accept NULL as well.
Only mlx4 uses an input request structure, have every other driver call ib_is_udata_in_empty() to enforce the lack of request structs.
Use ib_respond_empty_udata() in every driver that does not use a response struct.
Ensure a check for NULL udata before calling ib_respond_udata() in bnxt_re, efa, and mlx5.
Make mlx4 safe to be called with NULL.
--- drivers/infiniband/core/device.c | 3 +-- drivers/infiniband/hw/bnxt_re/ib_verbs.c | 5 ++++- drivers/infiniband/hw/cxgb4/provider.c | 8 +++++--- drivers/infiniband/hw/erdma/erdma_verbs.c | 9 +++++++-- drivers/infiniband/hw/hns/hns_roce_main.c | 7 ++++++- drivers/infiniband/hw/ionic/ionic_ibdev.c | 7 ++++++- drivers/infiniband/hw/irdma/verbs.c | 8 +++++--- drivers/infiniband/hw/mana/main.c | 7 ++++++- drivers/infiniband/hw/mlx4/main.c | 13 +++++++------ drivers/infiniband/hw/mthca/mthca_provider.c | 13 ++++++++----- drivers/infiniband/hw/ocrdma/ocrdma_verbs.c | 8 +++++--- drivers/infiniband/hw/qedr/verbs.c | 7 ++++++- drivers/infiniband/hw/usnic/usnic_ib_verbs.c | 8 +++++--- drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c | 8 +++++--- drivers/infiniband/sw/rdmavt/vt.c | 9 ++++++--- drivers/infiniband/sw/rxe/rxe_verbs.c | 14 ++++---------- drivers/infiniband/sw/siw/siw_verbs.c | 8 +++++--- 17 files changed, 91 insertions(+), 51 deletions(-)
drivers/infiniband/core/device.c +1 -2
@@ -1245,7 +1245,6 @@ static int assign_name(struct ib_device *device, const char *name)*/ static int setup_device (struct ib_device *device) { -struct ib_udata uhw = {.outlen =0 , .inlen =0 };int ret;ib_device_check_mandatory (device);
@@ -1257,7 +1256,7 @@ static int setup_device(struct ib_device *device) }memset (&device->attrs,0 ,sizeof (device->attrs)); - ret = device->ops.query_device (device, &device->attrs, &uhw); + ret = device->ops.query_device (device, &device->attrs,NULL );if (ret) {dev_warn (&device->dev,"Couldn't query the device attributes\n" );
drivers/infiniband/hw/bnxt_re/ib_verbs.c +4 -1
@@ -265,7 +265,10 @@ int bnxt_re_query_device(struct ib_device *ibdev, resp.packet_pacing_caps.supported_qpts =1 <<IB_QPT_RC ; } -return ib_respond_udata (udata, resp); + +if (udata) +return ib_respond_udata (udata, resp); +return 0 ; } int bnxt_re_modify_device(struct ib_device *ibdev,
drivers/infiniband/hw/cxgb4/provider.c +5 -3
@@ -259,11 +259,13 @@ static int c4iw_query_device(struct ib_device *ibdev, struct ib_device_attr *pro {struct c4iw_dev *dev; +int err;pr_debug ("ibdev %p\n" , ibdev); -if (uhw->inlen || uhw->outlen) -return -EINVAL ; + err =ib_is_udata_in_empty (uhw); +if (err) +return err; dev =to_c4iw_dev (ibdev); addrconf_addr_eui48((u8 *)&props->sys_image_guid,
@@ -298,7 +300,7 @@ static int c4iw_query_device(struct ib_device *ibdev, struct ib_device_attr *pro props->max_fast_reg_page_list_len =t4_max_fr_depth (dev->rdev.lldi.ulptx_memwrite_dsgl && use_dsgl); -return 0 ; +return ib_respond_empty_udata (uhw); } static int c4iw_query_port(struct ib_device *ibdev, u32 port,
drivers/infiniband/hw/erdma/erdma_verbs.c +7 -2
@@ -315,9 +315,14 @@ erdma_user_mmap_entry_insert(struct erdma_ucontext *uctx, void *address, }int erdma_query_device (struct ib_device *ibdev,struct ib_device_attr *attr, -struct ib_udata *unused) +struct ib_udata *udata) {struct erdma_dev *dev =to_edev (ibdev); +int err; + + err =ib_is_udata_in_empty (udata); +if (err) +return err;memset (attr,0 ,sizeof (*attr));
@@ -358,7 +363,7 @@ int erdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr,addrconf_addr_eui48 ((u8 *)&attr->sys_image_guid, dev->netdev->dev_addr); -return 0 ; +return ib_respond_empty_udata (udata); } int erdma_query_gid(struct ib_device *ibdev, u32 port, int idx,
drivers/infiniband/hw/hns/hns_roce_main.c +6 -1
@@ -221,6 +221,11 @@ static int hns_roce_query_device(struct ib_device *ib_dev, struct ib_udata *uhw) {struct hns_roce_dev *hr_dev =to_hr_dev (ib_dev); +int ret; + + ret =ib_is_udata_in_empty (uhw); +if (ret) +return ret;memset (props,0 ,sizeof (*props));
@@ -274,7 +279,7 @@ static int hns_roce_query_device(struct ib_device *ib_dev,if (hr_dev->caps.flags &HNS_ROCE_CAP_FLAG_XRC ) props->device_cap_flags |=IB_DEVICE_XRC ; -return 0 ; +return ib_respond_empty_udata (uhw); } static int hns_roce_query_port(struct ib_device *ib_dev, u32 port_num,
drivers/infiniband/hw/ionic/ionic_ibdev.c +6 -1
@@ -25,6 +25,11 @@ static int ionic_query_device(struct ib_device *ibdev, {struct ionic_ibdev *dev =to_ionic_ibdev (ibdev);struct net_device *ndev; +int err; + + err =ib_is_udata_in_empty (udata); +if (err) +return err; ndev =ib_device_get_netdev (ibdev,1 );addrconf_ifid_eui48 ((u8 *)&attr->sys_image_guid, ndev);
@@ -69,7 +74,7 @@ static int ionic_query_device(struct ib_device *ibdev, attr->max_fast_reg_page_list_len = dev->lif_cfg.npts_per_lif /2 ; attr->max_pkeys =IONIC_PKEY_TBL_LEN ; -return 0 ; +return ib_respond_empty_udata (udata); } static int ionic_query_port(struct ib_device *ibdev, u32 port,
drivers/infiniband/hw/irdma/verbs.c +5 -3
@@ -16,9 +16,11 @@ static int irdma_query_device(struct ib_device *ibdev,struct irdma_pci_f *rf = iwdev->rf;struct pci_dev *pcidev = iwdev->rf->pcidev;struct irdma_hw_attrs *hw_attrs = &rf->sc_dev.hw_attrs; +int err; -if (udata->inlen || udata->outlen) -return -EINVAL ; + err =ib_is_udata_in_empty (udata); +if (err) +return err;memset (props,0 ,sizeof (*props)); addrconf_addr_eui48((u8 *)&props->sys_image_guid,
@@ -74,7 +76,7 @@ static int irdma_query_device(struct ib_device *ibdev,if (hw_attrs->uk_attrs.hw_rev >=IRDMA_GEN_3 ) props->device_cap_flags |=IB_DEVICE_MEM_WINDOW_TYPE_2B ; -return 0 ; +return ib_respond_empty_udata (udata); }/**
drivers/infiniband/hw/mana/main.c +6 -1
@@ -549,6 +549,11 @@ int mana_ib_query_device(struct ib_device *ibdev, struct ib_device_attr *props, { struct mana_ib_dev *dev = container_of(ibdev, struct mana_ib_dev, ib_dev);struct pci_dev *pdev =to_pci_dev (mdev_to_gc (dev)->dev); +int err; + + err =ib_is_udata_in_empty (uhw); +if (err) +return err;memset (props,0 ,sizeof (*props)); props->vendor_id = pdev->vendor;
@@ -576,7 +581,7 @@ int mana_ib_query_device(struct ib_device *ibdev, struct ib_device_attr *props,if (!mana_ib_is_rnic (dev)) props->raw_packet_caps =IB_RAW_PACKET_CAP_IP_CSUM ; -return 0 ; +return ib_respond_empty_udata (uhw); } int mana_ib_query_port(struct ib_device *ibdev, u32 port,
drivers/infiniband/hw/mlx4/main.c +7 -6
@@ -444,8 +444,9 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,struct mlx4_uverbs_ex_query_device cmd;struct mlx4_uverbs_ex_query_device_resp resp = {};struct mlx4_clock_params clock_params; +size_t uhw_outlen = uhw ? uhw->outlen :0 ; -if (uhw->inlen) { +if (uhw && uhw->inlen) { err =ib_copy_validate_udata_in_cm (uhw, cmd, reserved,0 );if (err)return err;
@@ -572,7 +573,7 @@ static int mlx4_ib_query_device(struct ib_device *ibdev, props->cq_caps.max_cq_moderation_count =MLX4_MAX_CQ_COUNT ; props->cq_caps.max_cq_moderation_period =MLX4_MAX_CQ_PERIOD ; -if (uhw->outlen >= resp.response_length +sizeof (resp.hca_core_clock_offset)) { +if (uhw_outlen >= resp.response_length +sizeof (resp.hca_core_clock_offset)) { resp.response_length +=sizeof (resp.hca_core_clock_offset);if (!mlx4_get_internal_clock_params (dev->dev, &clock_params)) { resp.comp_mask |=MLX4_IB_QUERY_DEV_RESP_MASK_CORE_CLOCK_OFFSET ;
@@ -580,14 +581,14 @@ static int mlx4_ib_query_device(struct ib_device *ibdev, } } -if (uhw->outlen >= resp.response_length + +if (uhw_outlen >= resp.response_length +sizeof (resp.max_inl_recv_sz)) { resp.response_length +=sizeof (resp.max_inl_recv_sz); resp.max_inl_recv_sz = dev->dev->caps.max_rq_sg *sizeof (struct mlx4_wqe_data_seg ); } -if (offsetofend (typeof (resp), rss_caps) <= uhw->outlen) { +if (offsetofend (typeof (resp), rss_caps) <= uhw_outlen) {if (props->rss_caps.supported_qpts) { resp.rss_caps.rx_hash_function =MLX4_IB_RX_HASH_FUNC_TOEPLITZ ;
@@ -611,7 +612,7 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,sizeof (resp.rss_caps); } -if (offsetofend (typeof (resp), tso_caps) <= uhw->outlen) { +if (offsetofend (typeof (resp), tso_caps) <= uhw_outlen) { if (dev->dev->caps.max_gso_sz && ((mlx4_ib_port_link_layer(ibdev, 1) == IB_LINK_LAYER_ETHERNET) ||
@@ -625,7 +626,7 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,sizeof (resp.tso_caps); } -if (uhw->outlen) { +if (uhw_outlen) { err =ib_respond_udata (uhw, resp);if (err) goto out;
drivers/infiniband/hw/mthca/mthca_provider.c +8 -5
@@ -55,16 +55,19 @@ static int mthca_query_device(struct ib_device *ibdev, struct ib_device_attr *pr {struct ib_smp *in_mad;struct ib_smp *out_mad; -int err = -ENOMEM ; +int err;struct mthca_dev *mdev =to_mdev (ibdev); -if (uhw->inlen || uhw->outlen) -return -EINVAL ; + err =ib_is_udata_in_empty (uhw); +if (err) +return err; in_mad =kzalloc_obj (*in_mad); out_mad =kmalloc_obj (*out_mad); -if (!in_mad || !out_mad) +if (!in_mad || !out_mad) { + err = -ENOMEM ; goto out; + }memset (props,0 ,sizeof *props);
@@ -111,7 +114,7 @@ static int mthca_query_device(struct ib_device *ibdev, struct ib_device_attr *pr props->max_total_mcast_qp_attach = props->max_mcast_qp_attach * props->max_mcast_grp; - err =0 ; + err =ib_respond_empty_udata (uhw); out:kfree (in_mad);kfree (out_mad);
drivers/infiniband/hw/ocrdma/ocrdma_verbs.c +5 -3
@@ -68,9 +68,11 @@ int ocrdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr, struct ib_udata *uhw) {struct ocrdma_dev *dev =get_ocrdma_dev (ibdev); +int err; -if (uhw->inlen || uhw->outlen) -return -EINVAL ; + err =ib_is_udata_in_empty (uhw); +if (err) +return err;memset (attr,0 ,sizeof *attr); memcpy(&attr->fw_ver, &dev->attr.fw_ver[0],
@@ -110,7 +112,7 @@ int ocrdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr, attr->local_ca_ack_delay = dev->attr.local_ca_ack_delay; attr->max_fast_reg_page_list_len = dev->attr.max_pages_per_frmr; attr->max_pkeys =1 ; -return 0 ; +return ib_respond_empty_udata (uhw); } static inline void get_link_speed_and_width(struct ocrdma_dev *dev,
drivers/infiniband/hw/qedr/verbs.c +6 -1
@@ -105,6 +105,7 @@ int qedr_query_device(struct ib_device *ibdev, {struct qedr_dev *dev =get_qedr_dev (ibdev);struct qedr_device_attr *qattr = &dev->attr; +int rc;if (!dev->rdma_ctx) { DP_ERR(dev,
@@ -113,6 +114,10 @@ int qedr_query_device(struct ib_device *ibdev,return -EINVAL ; } + rc =ib_is_udata_in_empty (udata); +if (rc) +return rc; +memset (attr,0 ,sizeof (*attr)); attr->fw_ver = qattr->fw_ver;
@@ -155,7 +160,7 @@ int qedr_query_device(struct ib_device *ibdev, attr->max_pkeys = qattr->max_pkey; attr->max_ah = qattr->max_ah; -return 0 ; +return ib_respond_empty_udata (udata); } static inline void get_link_speed_and_width(int speed, u16 *ib_speed,
drivers/infiniband/hw/usnic/usnic_ib_verbs.c +5 -3
@@ -275,10 +275,12 @@ int usnic_ib_query_device(struct ib_device *ibdev,union ib_gid gid;struct ethtool_drvinfo info;int qp_per_vf; +int err;usnic_dbg ("\n" ); -if (uhw->inlen || uhw->outlen) -return -EINVAL ; + err =ib_is_udata_in_empty (uhw); +if (err) +return err;mutex_lock (&us_ibdev->usdev_lock); us_ibdev->netdev->ethtool_ops->get_drvinfo (us_ibdev->netdev, &info);
@@ -322,7 +324,7 @@ int usnic_ib_query_device(struct ib_device *ibdev,* max_qp_wr, max_sge, max_sge_rd, max_cqe */ mutex_unlock (&us_ibdev->usdev_lock); -return 0 ; +return ib_respond_empty_udata (uhw); } int usnic_ib_query_port(struct ib_device *ibdev, u32 port,
drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c +5 -3
@@ -67,9 +67,11 @@ int pvrdma_query_device(struct ib_device *ibdev, struct ib_udata *uhw) {struct pvrdma_dev *dev =to_vdev (ibdev); +int err; -if (uhw->inlen || uhw->outlen) -return -EINVAL ; + err =ib_is_udata_in_empty (uhw); +if (err) +return err; props->fw_ver = dev->dsr->caps.fw_ver; props->sys_image_guid = dev->dsr->caps.sys_image_guid;
@@ -114,7 +116,7 @@ int pvrdma_query_device(struct ib_device *ibdev, props->device_cap_flags |=IB_DEVICE_PORT_ACTIVE_EVENT |IB_DEVICE_RC_RNR_NAK_GEN ; -return 0 ; +return ib_respond_empty_udata (uhw); }/**
drivers/infiniband/sw/rdmavt/vt.c +6 -3
@@ -6,6 +6,7 @@#include <linux/module.h> #include <linux/kernel.h> #include <linux/dma-mapping.h> +#include <rdma/uverbs_ioctl.h> #include "vt.h" #include "cq.h" #include "trace.h"
@@ -79,14 +80,16 @@ static int rvt_query_device(struct ib_device *ibdev, struct ib_udata *uhw) {struct rvt_dev_info *rdi =ib_to_rvt (ibdev); +int err; -if (uhw->inlen || uhw->outlen) -return -EINVAL ; + err =ib_is_udata_in_empty (uhw); +if (err) +return err;/* * Return rvt_dev_info.dparms.props contents */ *props = rdi->dparms.props; -return 0 ; +return ib_respond_empty_udata (uhw); }static int rvt_get_numa_node (struct ib_device *ibdev)
drivers/infiniband/sw/rxe/rxe_verbs.c +4 -10
@@ -22,19 +22,13 @@ static int rxe_query_device(struct ib_device *ibdev,struct rxe_dev *rxe =to_rdev (ibdev);int err; -if (udata->inlen || udata->outlen) { -rxe_dbg_dev (rxe,"malformed udata\n" ); - err = -EINVAL ; - goto err_out; - } + err =ib_is_udata_in_empty (udata); +if (err) +return err;memcpy (attr, &rxe->attr,sizeof (*attr)); -return 0 ; - -err_out: -rxe_err_dev (rxe,"returned err = %d\n" , err); -return err; +return ib_respond_empty_udata (udata); } static int rxe_query_port(struct ib_device *ibdev,
drivers/infiniband/sw/siw/siw_verbs.c +5 -3
@@ -130,9 +130,11 @@ int siw_query_device(struct ib_device *base_dev, struct ib_device_attr *attr, struct ib_udata *udata) {struct siw_device *sdev =to_siw_dev (base_dev); +int rv; -if (udata->inlen || udata->outlen) -return -EINVAL ; + rv =ib_is_udata_in_empty (udata); +if (rv) +return rv;memset (attr,0 ,sizeof (*attr));
@@ -165,7 +167,7 @@ int siw_query_device(struct ib_device *base_dev, struct ib_device_attr *attr,addrconf_addr_eui48 ((u8 *)&attr->sys_image_guid, sdev->raw_gid); -return 0 ; +return ib_respond_empty_udata (udata); } int siw_query_port(struct ib_device *base_dev, u32 port,
Signature · 1 line
2.43.0
Quoted 25 lines · Jason Gunthorpe
Sashiko pointed out these are dangerous, and the
create_qp()one is in fact a bug. Thequery_deviceis just ugly old code.Remove the stack ib_udata's from both places.
Jason Gunthorpe (2):
RDMA/core: Don't make a dummyib_udataon the stack increate_qp
RDMA: Update thequery_device()opdrivers/infiniband/core/core_priv.h | 2 +- drivers/infiniband/core/device.c | 3 +-- drivers/infiniband/core/ib_core_uverbs.c | 12 +++++++++++ drivers/infiniband/core/rdma_core.h | 7 +++++++ drivers/infiniband/core/uverbs_cmd.c | 14 +------------ drivers/infiniband/core/uverbs_std_types_qp.c | 3 +-- drivers/infiniband/core/verbs.c | 20 ++++++++++--------- drivers/infiniband/hw/bnxt_re/ib_verbs.c | 5 ++++- drivers/infiniband/hw/cxgb4/provider.c | 8 +++++--- drivers/infiniband/hw/erdma/erdma_verbs.c | 9 +++++++-- drivers/infiniband/hw/hns/hns_roce_main.c | 7 ++++++- drivers/infiniband/hw/ionic/ionic_ibdev.c | 7 ++++++- drivers/infiniband/hw/irdma/verbs.c | 8 +++++--- drivers/infiniband/hw/mana/main.c | 7 ++++++- drivers/infiniband/hw/mlx4/main.c | 13 ++++++------ drivers/infiniband/hw/mthca/mthca_provider.c | 13 +++++++-----
Quoted 8 lines
drivers/infiniband/hw/ocrdma/ocrdma_verbs.c | 8 +++++--- drivers/infiniband/hw/qedr/verbs.c | 7 ++++++- drivers/infiniband/hw/usnic/usnic_ib_verbs.c | 8 +++++--- .../infiniband/hw/vmw_pvrdma/pvrdma_verbs.c | 8 +++++--- drivers/infiniband/sw/rdmavt/vt.c | 9 ++++++--- drivers/infiniband/sw/rxe/rxe_verbs.c | 14 ++++--------- drivers/infiniband/sw/siw/siw_verbs.c | 8 +++++--- 23 files changed, 124 insertions(+), 76 deletions(-)
Applied to for-next
Jason