Skip to content

Commit 1f3b337

Browse files
gurmichaeljgunthorpe
authored andcommitted
RDMA/core: Fix rereg_mr use-after-free race
When a driver creates a new MR during rereg_user_mr, a race window exists between rdma_alloc_commit_uobject() for the new MR and the point where the code reads that MR to populate the response keys. A concurrent rereg_mr or destroy_mr could destroy the MR in this window and cause UAF in the first thread. Racing flow between two rereg_mr calls: CPU0 CPU1 ---- ---- rereg_user_mr(mr_handle) uobj_get_write(mr_handle) -> mr0 mr1 = driver→rereg() rdma_alloc_commit_uobject(mr1) // mr1 replaced mr0 and is unlocked uobj_put_destroy(mr0) rereg_user_mr(mr_handle) uobj_get_write(mr_handle) -> mr1 mr2 = driver→rereg() rdma_alloc_commit_uobject(mr2) // mr2 replaced mr1 and is unlocked uobj_put_destroy(mr1) // Destroys mr1! resp.lkey = mr1->lkey; // UAF - mr1 was freed! resp.rkey = mr1->rkey; // UAF - mr1 was freed! Fix by storing lkey/rkey in local variables before the new MR is unlocked and using the local variables to set the user response. Fixes: 6e0954b ("RDMA/uverbs: Allow drivers to create a new HW object during rereg_mr") Link: https://patch.msgid.link/r/20260427-security-bug-fixes-v3-4-4621fa52de0e@nvidia.com Signed-off-by: Michael Guralnik <michaelgur@nvidia.com> Reviewed-by: Maher Sanalla <msanalla@nvidia.com> Signed-off-by: Edward Srouji <edwards@nvidia.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
1 parent 610771c commit 1f3b337

1 file changed

Lines changed: 7 additions & 2 deletions

File tree

drivers/infiniband/core/uverbs_cmd.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,7 @@ static int ib_uverbs_rereg_mr(struct uverbs_attr_bundle *attrs)
778778
struct ib_pd *orig_pd;
779779
struct ib_pd *new_pd;
780780
struct ib_mr *new_mr;
781+
u32 lkey, rkey;
781782

782783
ret = uverbs_request(attrs, &cmd, sizeof(cmd));
783784
if (ret)
@@ -846,6 +847,8 @@ static int ib_uverbs_rereg_mr(struct uverbs_attr_bundle *attrs)
846847
new_mr->uobject = uobj;
847848
atomic_inc(&new_pd->usecnt);
848849
new_uobj->object = new_mr;
850+
lkey = new_mr->lkey;
851+
rkey = new_mr->rkey;
849852

850853
rdma_restrack_new(&new_mr->res, RDMA_RESTRACK_MR);
851854
rdma_restrack_set_name(&new_mr->res, NULL);
@@ -871,11 +874,13 @@ static int ib_uverbs_rereg_mr(struct uverbs_attr_bundle *attrs)
871874
mr->iova = cmd.hca_va;
872875
mr->length = cmd.length;
873876
}
877+
lkey = mr->lkey;
878+
rkey = mr->rkey;
874879
}
875880

876881
memset(&resp, 0, sizeof(resp));
877-
resp.lkey = mr->lkey;
878-
resp.rkey = mr->rkey;
882+
resp.lkey = lkey;
883+
resp.rkey = rkey;
879884

880885
ret = uverbs_response(attrs, &resp, sizeof(resp));
881886

0 commit comments

Comments
 (0)