>-----Original Message----- >From: linux-rdma-owner@xxxxxxxxxxxxxxx [mailto:linux-rdma- >owner@xxxxxxxxxxxxxxx] On Behalf Of Leon Romanovsky >Sent: Monday, January 28, 2019 2:18 PM >To: Doug Ledford <dledford@xxxxxxxxxx>; Jason Gunthorpe ><jgg@xxxxxxxxxxxx> >Cc: Leon Romanovsky <leonro@xxxxxxxxxxxx>; RDMA mailing list <linux- >rdma@xxxxxxxxxxxxxxx> >Subject: [PATCH rdma-next v2] RDMA: Provide safe ib_alloc_device() function > >From: Leon Romanovsky <leonro@xxxxxxxxxxxx> > >All callers to ib_alloc_device() provides larger size than struct >ib_device and rely on the fact that struct ib_device is embedded >in their structure. Provide safer variant of ib_alloc_device() >to make sure that struct ib_device is embedded as first field >in their structure. > >Signed-off-by: Leon Romanovsky <leonro@xxxxxxxxxxxx> >--- >Changelog > v1 -> v2: > * Used Jason's macro. > v0 -> v1: > * Rewrote macro as suggested by Bart >--- > drivers/infiniband/core/device.c | 6 +++--- > drivers/infiniband/hw/bnxt_re/main.c | 2 +- > drivers/infiniband/hw/cxgb3/iwch.c | 2 +- > drivers/infiniband/hw/cxgb4/device.c | 2 +- > drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 2 +- > drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 2 +- > drivers/infiniband/hw/i40iw/i40iw_verbs.c | 2 +- > drivers/infiniband/hw/mlx4/main.c | 2 +- > drivers/infiniband/hw/mlx5/ib_rep.c | 2 +- > drivers/infiniband/hw/mlx5/main.c | 2 +- > drivers/infiniband/hw/mthca/mthca_main.c | 2 +- > drivers/infiniband/hw/nes/nes_verbs.c | 2 +- > drivers/infiniband/hw/ocrdma/ocrdma_main.c | 2 +- > drivers/infiniband/hw/qedr/main.c | 2 +- > drivers/infiniband/hw/usnic/usnic_ib_main.c | 2 +- > drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c | 2 +- > drivers/infiniband/sw/rdmavt/vt.c | 2 +- > drivers/infiniband/sw/rxe/rxe_net.c | 2 +- > include/rdma/ib_verbs.h | 8 +++++++- > 19 files changed, 27 insertions(+), 21 deletions(-) > >diff --git a/drivers/infiniband/core/device.c >b/drivers/infiniband/core/device.c >index e380a2663f31..28e4c8f5a75b 100644 >--- a/drivers/infiniband/core/device.c >+++ b/drivers/infiniband/core/device.c >@@ -268,7 +268,7 @@ static struct class ib_class = { > }; > > /** >- * ib_alloc_device - allocate an IB device struct >+ * _ib_alloc_device - allocate an IB device struct > * @size:size of structure to allocate > * > * Low-level drivers should use ib_alloc_device() to allocate &struct >@@ -277,7 +277,7 @@ static struct class ib_class = { > * ib_dealloc_device() must be used to free structures allocated with > * ib_alloc_device(). > */ >-struct ib_device *ib_alloc_device(size_t size) >+struct ib_device *_ib_alloc_device(size_t size) > { > struct ib_device *device; > >@@ -306,7 +306,7 @@ struct ib_device *ib_alloc_device(size_t size) > > return device; > } >-EXPORT_SYMBOL(ib_alloc_device); >+EXPORT_SYMBOL(_ib_alloc_device); > > /** > * ib_dealloc_device - free an IB device struct ... >diff --git a/drivers/infiniband/sw/rdmavt/vt.c >b/drivers/infiniband/sw/rdmavt/vt.c >index 5c4253a4524b..fea1ae642a8f 100644 >--- a/drivers/infiniband/sw/rdmavt/vt.c >+++ b/drivers/infiniband/sw/rdmavt/vt.c >@@ -91,7 +91,7 @@ struct rvt_dev_info *rvt_alloc_device(size_t size, int >nports) > { > struct rvt_dev_info *rdi; > >- rdi = (struct rvt_dev_info *)ib_alloc_device(size); >+ rdi = _ib_alloc_device(size); > if (!rdi) > return rdi; > >diff --git a/drivers/infiniband/sw/rxe/rxe_net.c >b/drivers/infiniband/sw/rxe/rxe_net.c >index 8fd03ae20efc..19f3c69916b1 100644 >--- a/drivers/infiniband/sw/rxe/rxe_net.c >+++ b/drivers/infiniband/sw/rxe/rxe_net.c >@@ -555,7 +555,7 @@ struct rxe_dev *rxe_net_add(struct net_device >*ndev) > int err; > struct rxe_dev *rxe = NULL; > >- rxe = (struct rxe_dev *)ib_alloc_device(sizeof(*rxe)); >+ rxe = ib_alloc_device(rxe_dev, ib_dev); > if (!rxe) > return NULL; > >diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h >index ceb2f75c8421..ce7446d7980a 100644 >--- a/include/rdma/ib_verbs.h >+++ b/include/rdma/ib_verbs.h >@@ -2638,7 +2638,13 @@ struct ib_client { > struct list_head list; > }; > >-struct ib_device *ib_alloc_device(size_t size); >+struct ib_device *_ib_alloc_device(size_t size); >+#define ib_alloc_device(drv_struct, member) \ This precludes being able to use variably sized data structure (ala rdmavt). Would augmenting this to #define ib_alloc_device(size, drv_struct, member) Be an additional way do this type checking? M >+ container_of(_ib_alloc_device(sizeof(struct drv_struct) + \ >+ BUILD_BUG_ON_ZERO(offsetof( \ >+ struct drv_struct, member))), \ >+ struct drv_struct, member) >+ > void ib_dealloc_device(struct ib_device *device); > > void ib_get_device_fw_str(struct ib_device *device, char *str); >-- >2.19.1