Blame SOURCES/CVE-2020-36385.patch

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