Blame SOURCES/CVE-2021-3609.patch

d46c83
From 61fe578156c4c9bad13e83efdf4a1546c1bab3cd Mon Sep 17 00:00:00 2001
d46c83
From: Artem Savkov <asavkov@redhat.com>
d46c83
Date: Mon, 26 Jul 2021 12:27:34 +0200
d46c83
Subject: [PATCH] can: bcm: delay release of struct bcm_op after
d46c83
 synchronize_rcu()
d46c83
d46c83
Kernels:
d46c83
4.18.0-305.el8
d46c83
4.18.0-305.3.1.el8_4
d46c83
4.18.0-305.7.1.el8_4
d46c83
4.18.0-305.10.2.el8_4
d46c83
d46c83
Changes since last build:
d46c83
arches: x86_64 ppc64le
d46c83
bcm.o: changed function: bcm_release
d46c83
bcm.o: changed function: bcm_sendmsg
d46c83
---------------------------
d46c83
d46c83
Kernels:
d46c83
4.18.0-305.el8
d46c83
4.18.0-305.3.1.el8_4
d46c83
4.18.0-305.7.1.el8_4
d46c83
4.18.0-305.10.2.el8_4
d46c83
d46c83
Modifications: none
d46c83
d46c83
commit 14c1d51567d0ef31ef900f6d1641615924fdb239
d46c83
Author: Hangbin Liu <haliu@redhat.com>
d46c83
Date:   Mon Jun 28 14:50:49 2021 +0800
d46c83
d46c83
    can: bcm: delay release of struct bcm_op after synchronize_rcu()
d46c83
d46c83
    Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1975058
d46c83
    Y-Commit: fc088504ba6bee277b7bdc93ab0988b648bb8b81
d46c83
d46c83
    Upstream Status: net.git commit d5f9023fa61e
d46c83
    CVE: CVE-2021-3609
d46c83
    O-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1975059
d46c83
d46c83
    commit d5f9023fa61ee8b94f37a93f08e94b136cf1e463
d46c83
    Author: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
d46c83
    Date:   Sat Jun 19 13:18:13 2021 -0300
d46c83
d46c83
        can: bcm: delay release of struct bcm_op after synchronize_rcu()
d46c83
d46c83
        can_rx_register() callbacks may be called concurrently to the call to
d46c83
        can_rx_unregister(). The callbacks and callback data, though, are
d46c83
        protected by RCU and the struct sock reference count.
d46c83
d46c83
        So the callback data is really attached to the life of sk, meaning
d46c83
        that it should be released on sk_destruct. However, bcm_remove_op()
d46c83
        calls tasklet_kill(), and RCU callbacks may be called under RCU
d46c83
        softirq, so that cannot be used on kernels before the introduction of
d46c83
        HRTIMER_MODE_SOFT.
d46c83
d46c83
        However, bcm_rx_handler() is called under RCU protection, so after
d46c83
        calling can_rx_unregister(), we may call synchronize_rcu() in order to
d46c83
        wait for any RCU read-side critical sections to finish. That is,
d46c83
        bcm_rx_handler() won't be called anymore for those ops. So, we only
d46c83
        free them, after we do that synchronize_rcu().
d46c83
d46c83
        Fixes: ffd980f976e7 ("[CAN]: Add broadcast manager (bcm) protocol")
d46c83
        Link: https://lore.kernel.org/r/20210619161813.2098382-1-cascardo@canonical.com
d46c83
        Cc: linux-stable <stable@vger.kernel.org>
d46c83
        Reported-by: syzbot+0f7e7e5e2f4f40fa89c0@syzkaller.appspotmail.com
d46c83
        Reported-by: Norbert Slusarek <nslusarek@gmx.net>
d46c83
        Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
d46c83
        Acked-by: Oliver Hartkopp <socketcan@hartkopp.net>
d46c83
        Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
d46c83
d46c83
    Signed-off-by: Hangbin Liu <haliu@redhat.com>
d46c83
d46c83
Signed-off-by: Artem Savkov <asavkov@redhat.com>
d46c83
Acked-by: Joe Lawrence <joe.lawrence@redhat.com>
d46c83
---
d46c83
 net/can/bcm.c | 7 ++++++-
d46c83
 1 file changed, 6 insertions(+), 1 deletion(-)
d46c83
d46c83
diff --git a/net/can/bcm.c b/net/can/bcm.c
d46c83
index 0af8f0db892a3..4ee2fd682afaa 100644
d46c83
--- a/net/can/bcm.c
d46c83
+++ b/net/can/bcm.c
d46c83
@@ -802,6 +802,7 @@ static int bcm_delete_rx_op(struct list_head *ops, struct bcm_msg_head *mh,
d46c83
 						  bcm_rx_handler, op);
d46c83
 
d46c83
 			list_del(&op->list);
d46c83
+			synchronize_rcu();
d46c83
 			bcm_remove_op(op);
d46c83
 			return 1; /* done */
d46c83
 		}
d46c83
@@ -1527,9 +1528,13 @@ static int bcm_release(struct socket *sock)
d46c83
 					  REGMASK(op->can_id),
d46c83
 					  bcm_rx_handler, op);
d46c83
 
d46c83
-		bcm_remove_op(op);
d46c83
 	}
d46c83
 
d46c83
+	synchronize_rcu();
d46c83
+
d46c83
+	list_for_each_entry_safe(op, next, &bo->rx_ops, list)
d46c83
+		bcm_remove_op(op);
d46c83
+
d46c83
 #if IS_ENABLED(CONFIG_PROC_FS)
d46c83
 	/* remove procfs entry */
d46c83
 	if (net->can.bcmproc_dir && bo->bcm_proc_read)
d46c83
-- 
d46c83
2.26.3
d46c83