Skip to content

Commit bb6d73d

Browse files
cnbednarrleon
authored andcommitted
RDMA/irdma: Prevent zero-length STAG registration
Currently irdma allows zero-length STAGs to be programmed in HW during the kernel mode fast register flow. Zero-length MR or STAG registration disable HW memory length checks. Improve gaps in bounds checking in irdma by preventing zero-length STAG or MR registrations except if the IB_PD_UNSAFE_GLOBAL_RKEY is set. This addresses the disclosure CVE-2023-25775. Fixes: b48c24c ("RDMA/irdma: Implement device supported verb APIs") Signed-off-by: Christopher Bednarz <[email protected]> Signed-off-by: Shiraz Saleem <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Leon Romanovsky <[email protected]>
1 parent ed10435 commit bb6d73d

File tree

3 files changed

+16
-2
lines changed

3 files changed

+16
-2
lines changed

drivers/infiniband/hw/irdma/ctrl.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,6 +1061,9 @@ static int irdma_sc_alloc_stag(struct irdma_sc_dev *dev,
10611061
u64 hdr;
10621062
enum irdma_page_size page_size;
10631063

1064+
if (!info->total_len && !info->all_memory)
1065+
return -EINVAL;
1066+
10641067
if (info->page_size == 0x40000000)
10651068
page_size = IRDMA_PAGE_SIZE_1G;
10661069
else if (info->page_size == 0x200000)
@@ -1126,6 +1129,9 @@ static int irdma_sc_mr_reg_non_shared(struct irdma_sc_dev *dev,
11261129
u8 addr_type;
11271130
enum irdma_page_size page_size;
11281131

1132+
if (!info->total_len && !info->all_memory)
1133+
return -EINVAL;
1134+
11291135
if (info->page_size == 0x40000000)
11301136
page_size = IRDMA_PAGE_SIZE_1G;
11311137
else if (info->page_size == 0x200000)

drivers/infiniband/hw/irdma/type.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -969,6 +969,7 @@ struct irdma_allocate_stag_info {
969969
bool remote_access:1;
970970
bool use_hmc_fcn_index:1;
971971
bool use_pf_rid:1;
972+
bool all_memory:1;
972973
u8 hmc_fcn_index;
973974
};
974975

@@ -996,6 +997,7 @@ struct irdma_reg_ns_stag_info {
996997
bool use_hmc_fcn_index:1;
997998
u8 hmc_fcn_index;
998999
bool use_pf_rid:1;
1000+
bool all_memory:1;
9991001
};
10001002

10011003
struct irdma_fast_reg_stag_info {

drivers/infiniband/hw/irdma/verbs.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2624,7 +2624,8 @@ static int irdma_hw_alloc_stag(struct irdma_device *iwdev,
26242624
struct irdma_mr *iwmr)
26252625
{
26262626
struct irdma_allocate_stag_info *info;
2627-
struct irdma_pd *iwpd = to_iwpd(iwmr->ibmr.pd);
2627+
struct ib_pd *pd = iwmr->ibmr.pd;
2628+
struct irdma_pd *iwpd = to_iwpd(pd);
26282629
int status;
26292630
struct irdma_cqp_request *cqp_request;
26302631
struct cqp_cmds_info *cqp_info;
@@ -2640,6 +2641,7 @@ static int irdma_hw_alloc_stag(struct irdma_device *iwdev,
26402641
info->stag_idx = iwmr->stag >> IRDMA_CQPSQ_STAG_IDX_S;
26412642
info->pd_id = iwpd->sc_pd.pd_id;
26422643
info->total_len = iwmr->len;
2644+
info->all_memory = pd->flags & IB_PD_UNSAFE_GLOBAL_RKEY;
26432645
info->remote_access = true;
26442646
cqp_info->cqp_cmd = IRDMA_OP_ALLOC_STAG;
26452647
cqp_info->post_sq = 1;
@@ -2687,6 +2689,8 @@ static struct ib_mr *irdma_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
26872689
iwmr->type = IRDMA_MEMREG_TYPE_MEM;
26882690
palloc = &iwpbl->pble_alloc;
26892691
iwmr->page_cnt = max_num_sg;
2692+
/* Use system PAGE_SIZE as the sg page sizes are unknown at this point */
2693+
iwmr->len = max_num_sg * PAGE_SIZE;
26902694
err_code = irdma_get_pble(iwdev->rf->pble_rsrc, palloc, iwmr->page_cnt,
26912695
false);
26922696
if (err_code)
@@ -2766,7 +2770,8 @@ static int irdma_hwreg_mr(struct irdma_device *iwdev, struct irdma_mr *iwmr,
27662770
{
27672771
struct irdma_pbl *iwpbl = &iwmr->iwpbl;
27682772
struct irdma_reg_ns_stag_info *stag_info;
2769-
struct irdma_pd *iwpd = to_iwpd(iwmr->ibmr.pd);
2773+
struct ib_pd *pd = iwmr->ibmr.pd;
2774+
struct irdma_pd *iwpd = to_iwpd(pd);
27702775
struct irdma_pble_alloc *palloc = &iwpbl->pble_alloc;
27712776
struct irdma_cqp_request *cqp_request;
27722777
struct cqp_cmds_info *cqp_info;
@@ -2785,6 +2790,7 @@ static int irdma_hwreg_mr(struct irdma_device *iwdev, struct irdma_mr *iwmr,
27852790
stag_info->total_len = iwmr->len;
27862791
stag_info->access_rights = irdma_get_mr_access(access);
27872792
stag_info->pd_id = iwpd->sc_pd.pd_id;
2793+
stag_info->all_memory = pd->flags & IB_PD_UNSAFE_GLOBAL_RKEY;
27882794
if (stag_info->access_rights & IRDMA_ACCESS_FLAGS_ZERO_BASED)
27892795
stag_info->addr_type = IRDMA_ADDR_TYPE_ZERO_BASED;
27902796
else

0 commit comments

Comments
 (0)