Blame SOURCES/CVE-2021-3609.patch

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