|
|
0b4453 |
From e77f229ecaf387f9f54430dbd277baf8c60b2716 Mon Sep 17 00:00:00 2001
|
|
|
0b4453 |
From: Joe Lawrence <joe.lawrence@redhat.com>
|
|
|
0b4453 |
Date: Wed, 27 Oct 2021 13:17:13 -0400
|
|
|
0b4453 |
Subject: [KPATCH CVE-2020-36385] RDMA/ucma: kpatch fixes for CVE-2020-36385
|
|
|
0b4453 |
|
|
|
0b4453 |
Kernels:
|
|
|
0b4453 |
3.10.0-1160.6.1.el7
|
|
|
0b4453 |
3.10.0-1160.11.1.el7
|
|
|
0b4453 |
3.10.0-1160.15.2.el7
|
|
|
0b4453 |
3.10.0-1160.21.1.el7
|
|
|
0b4453 |
3.10.0-1160.24.1.el7
|
|
|
0b4453 |
3.10.0-1160.25.1.el7
|
|
|
0b4453 |
3.10.0-1160.31.1.el7
|
|
|
0b4453 |
3.10.0-1160.36.2.el7
|
|
|
0b4453 |
3.10.0-1160.41.1.el7
|
|
|
0b4453 |
3.10.0-1160.42.2.el7
|
|
|
0b4453 |
3.10.0-1160.45.1.el7
|
|
|
0b4453 |
|
|
|
0b4453 |
Changes since last build:
|
|
|
0b4453 |
arches: x86_64 ppc64le
|
|
|
0b4453 |
ucma.o: changed function: ucma_migrate_id
|
|
|
0b4453 |
---------------------------
|
|
|
0b4453 |
|
|
|
0b4453 |
Kpatch-MR: https://gitlab.com/redhat/prdsc/rhel/src/kpatch/rhel-7/-/merge_requests/12
|
|
|
0b4453 |
Approved-by: Artem Savkov (@artem.savkov)
|
|
|
0b4453 |
Modifications:
|
|
|
0b4453 |
- Avoid the complications of reworking all the locks (and preceding
|
|
|
0b4453 |
commits) and apply a minimal patch to avoid the CVE condition.
|
|
|
0b4453 |
- Always inline ucma_unlock_files() to avoid new function on x64_64
|
|
|
0b4453 |
|
|
|
0b4453 |
Z-MR: https://gitlab.com/redhat/rhel/src/kernel/rhel-7/-/merge_requests/231
|
|
|
0b4453 |
|
|
|
0b4453 |
KT0 test PASS: https://beaker.engineering.redhat.com/jobs/5948342
|
|
|
0b4453 |
for kpatch-patch-3_10_0-1160_6_1-1-11.el7 scratch build:
|
|
|
0b4453 |
https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=40661892
|
|
|
0b4453 |
|
|
|
0b4453 |
commit c71835cc23a3793651a693ea6cb1100e0eb9a0b1
|
|
|
0b4453 |
Author: Kamal Heib <kheib@redhat.com>
|
|
|
0b4453 |
Date: Sun Aug 1 10:49:07 2021 +0300
|
|
|
0b4453 |
|
|
|
0b4453 |
RDMA/ucma: Rework ucma_migrate_id() to avoid races with destroy
|
|
|
0b4453 |
|
|
|
0b4453 |
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1978075
|
|
|
0b4453 |
CVE: CVE-2020-36385
|
|
|
0b4453 |
Conflicts:
|
|
|
0b4453 |
Adjust the patch to use "mut" mutext instead xa_lock due to the missing
|
|
|
0b4453 |
of: afcafe07af0e ("ucma: Convert ctx_idr to XArray").
|
|
|
0b4453 |
|
|
|
0b4453 |
commit f5449e74802c1112dea984aec8af7a33c4516af1
|
|
|
0b4453 |
Author: Jason Gunthorpe <jgg@nvidia.com>
|
|
|
0b4453 |
Date: Mon Sep 14 08:59:56 2020 -0300
|
|
|
0b4453 |
|
|
|
0b4453 |
RDMA/ucma: Rework ucma_migrate_id() to avoid races with destroy
|
|
|
0b4453 |
|
|
|
0b4453 |
ucma_destroy_id() assumes that all things accessing the ctx will do so via
|
|
|
0b4453 |
the xarray. This assumption violated only in the case the FD is being
|
|
|
0b4453 |
closed, then the ctx is reached via the ctx_list. Normally this is OK
|
|
|
0b4453 |
since ucma_destroy_id() cannot run concurrenty with release(), however
|
|
|
0b4453 |
with ucma_migrate_id() is involved this can violated as the close of the
|
|
|
0b4453 |
2nd FD can run concurrently with destroy on the first:
|
|
|
0b4453 |
|
|
|
0b4453 |
CPU0 CPU1
|
|
|
0b4453 |
ucma_destroy_id(fda)
|
|
|
0b4453 |
ucma_migrate_id(fda -> fdb)
|
|
|
0b4453 |
ucma_get_ctx()
|
|
|
0b4453 |
xa_lock()
|
|
|
0b4453 |
_ucma_find_context()
|
|
|
0b4453 |
xa_erase()
|
|
|
0b4453 |
xa_unlock()
|
|
|
0b4453 |
xa_lock()
|
|
|
0b4453 |
ctx->file = new_file
|
|
|
0b4453 |
list_move()
|
|
|
0b4453 |
xa_unlock()
|
|
|
0b4453 |
ucma_put_ctx()
|
|
|
0b4453 |
|
|
|
0b4453 |
ucma_close(fdb)
|
|
|
0b4453 |
_destroy_id()
|
|
|
0b4453 |
kfree(ctx)
|
|
|
0b4453 |
|
|
|
0b4453 |
_destroy_id()
|
|
|
0b4453 |
wait_for_completion()
|
|
|
0b4453 |
// boom, ctx was freed
|
|
|
0b4453 |
|
|
|
0b4453 |
The ctx->file must be modified under the handler and xa_lock, and prior to
|
|
|
0b4453 |
modification the ID must be rechecked that it is still reachable from
|
|
|
0b4453 |
cur_file, ie there is no parallel destroy or migrate.
|
|
|
0b4453 |
|
|
|
0b4453 |
To make this work remove the double locking and streamline the control
|
|
|
0b4453 |
flow. The double locking was obsoleted by the handler lock now directly
|
|
|
0b4453 |
preventing new uevents from being created, and the ctx_list cannot be read
|
|
|
0b4453 |
while holding fgets on both files. Removing the double locking also
|
|
|
0b4453 |
removes the need to check for the same file.
|
|
|
0b4453 |
|
|
|
0b4453 |
Fixes: 88314e4dda1e ("RDMA/cma: add support for rdma_migrate_id()")
|
|
|
0b4453 |
Link: https://lore.kernel.org/r/0-v1-05c5a4090305+3a872-ucma_syz_migrate_jgg@nvidia.com
|
|
|
0b4453 |
Reported-and-tested-by: syzbot+cc6fc752b3819e082d0c@syzkaller.appspotmail.com
|
|
|
0b4453 |
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
|
|
|
0b4453 |
|
|
|
0b4453 |
Signed-off-by: Kamal Heib <kheib@redhat.com>
|
|
|
0b4453 |
|
|
|
0b4453 |
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
|
|
|
0b4453 |
---
|
|
|
0b4453 |
drivers/infiniband/core/ucma.c | 11 ++++++++++-
|
|
|
0b4453 |
1 file changed, 10 insertions(+), 1 deletion(-)
|
|
|
0b4453 |
|
|
|
0b4453 |
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
|
|
|
0b4453 |
index 608a780d9ebb..72e7eb893d03 100644
|
|
|
0b4453 |
--- a/drivers/infiniband/core/ucma.c
|
|
|
0b4453 |
+++ b/drivers/infiniband/core/ucma.c
|
|
|
0b4453 |
@@ -1547,7 +1547,7 @@ static void ucma_lock_files(struct ucma_file *file1, struct ucma_file *file2)
|
|
|
0b4453 |
}
|
|
|
0b4453 |
}
|
|
|
0b4453 |
|
|
|
0b4453 |
-static void ucma_unlock_files(struct ucma_file *file1, struct ucma_file *file2)
|
|
|
0b4453 |
+static __always_inline void ucma_unlock_files(struct ucma_file *file1, struct ucma_file *file2)
|
|
|
0b4453 |
{
|
|
|
0b4453 |
if (file1 < file2) {
|
|
|
0b4453 |
mutex_unlock(&file2->mut);
|
|
|
0b4453 |
@@ -1610,6 +1610,14 @@ static ssize_t ucma_migrate_id(struct ucma_file *new_file,
|
|
|
0b4453 |
ucma_lock_files(cur_file, new_file);
|
|
|
0b4453 |
mutex_lock(&mut;;
|
|
|
0b4453 |
|
|
|
0b4453 |
+ /* CVE-2020-36385 kpatch: double check the context one last time */
|
|
|
0b4453 |
+ if (_ucma_find_context(cmd.id, cur_file) != ctx) {
|
|
|
0b4453 |
+ mutex_unlock(&mut;;
|
|
|
0b4453 |
+ ucma_unlock_files(cur_file, new_file);
|
|
|
0b4453 |
+ ret = -ENOENT;
|
|
|
0b4453 |
+ goto err_unlock;
|
|
|
0b4453 |
+ }
|
|
|
0b4453 |
+
|
|
|
0b4453 |
list_move_tail(&ctx->list, &new_file->ctx_list);
|
|
|
0b4453 |
ucma_move_events(ctx, new_file);
|
|
|
0b4453 |
ctx->file = new_file;
|
|
|
0b4453 |
@@ -1623,6 +1631,7 @@ response:
|
|
|
0b4453 |
&resp, sizeof(resp)))
|
|
|
0b4453 |
ret = -EFAULT;
|
|
|
0b4453 |
|
|
|
0b4453 |
+err_unlock:
|
|
|
0b4453 |
ucma_put_ctx(ctx);
|
|
|
0b4453 |
file_put:
|
|
|
0b4453 |
fdput(f);
|
|
|
0b4453 |
--
|
|
|
0b4453 |
2.26.3
|
|
|
0b4453 |
|
|
|
0b4453 |
|