Blame SOURCES/CVE-2020-36385.patch

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