[SRU Focal 2/3] RDMA/ucma: Fix the locking of ctx->file
Thadeu Lima de Souza Cascardo
cascardo at canonical.com
Mon Oct 11 22:08:15 UTC 2021
From: Jason Gunthorpe <jgg at nvidia.com>
ctx->file is changed under the file->mut lock by ucma_migrate_id(), which
is impossible to lock correctly. Instead change ctx->file under the
handler_lock and ctx_table lock and revise all places touching ctx->file
to use this locking when reading ctx->file.
Link: https://lore.kernel.org/r/20200818120526.702120-9-leon@kernel.org
Signed-off-by: Leon Romanovsky <leonro at mellanox.com>
Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
(backported from commit 09e328e47a695b0d346598f5d6593ee598e64885)
[cascardo: commit 95fe51096b7adf1d1e7315c49c75e2f75f162584 moved the
file locks from ucma_cleanup_mc_events callers to inside it, keep it
out of the function]
CVE-2020-36385
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo at canonical.com>
---
drivers/infiniband/core/ucma.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index 7ecb094dc7ad..0755a4111d8d 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -545,6 +545,7 @@ static void ucma_cleanup_mc_events(struct ucma_multicast *mc)
{
struct ucma_event *uevent, *tmp;
+ rdma_lock_handler(mc->ctx->cm_id);
list_for_each_entry_safe(uevent, tmp, &mc->ctx->file->event_list, list) {
if (uevent->mc != mc)
continue;
@@ -552,6 +553,7 @@ static void ucma_cleanup_mc_events(struct ucma_multicast *mc)
list_del(&uevent->list);
kfree(uevent);
}
+ rdma_unlock_handler(mc->ctx->cm_id);
}
/*
@@ -1548,7 +1550,7 @@ static ssize_t ucma_leave_multicast(struct ucma_file *file,
mc = xa_load(&multicast_table, cmd.id);
if (!mc)
mc = ERR_PTR(-ENOENT);
- else if (mc->ctx->file != file)
+ else if (READ_ONCE(mc->ctx->file) != file)
mc = ERR_PTR(-EINVAL);
else if (!atomic_inc_not_zero(&mc->ctx->ref))
mc = ERR_PTR(-ENXIO);
@@ -1643,6 +1645,7 @@ static ssize_t ucma_migrate_id(struct ucma_file *new_file,
goto file_put;
}
+ rdma_lock_handler(ctx->cm_id);
cur_file = ctx->file;
if (cur_file == new_file) {
mutex_lock(&cur_file->mut);
@@ -1671,6 +1674,7 @@ static ssize_t ucma_migrate_id(struct ucma_file *new_file,
&resp, sizeof(resp)))
ret = -EFAULT;
+ rdma_unlock_handler(ctx->cm_id);
ucma_put_ctx(ctx);
file_put:
fdput(f);
--
2.30.2
More information about the kernel-team
mailing list