From: Greg Kroah-Hartman Date: Sat, 29 Jan 2022 11:32:39 +0000 (+0100) Subject: 4.9-stable patches X-Git-Tag: v5.4.176~103 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=078a3ad2bf6f4b0ca33de62833853530c4dd966b;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: can-bcm-fix-uaf-of-bcm-op.patch --- diff --git a/queue-4.14/series b/queue-4.14/series new file mode 100644 index 00000000000..e69de29bb2d diff --git a/queue-4.9/can-bcm-fix-uaf-of-bcm-op.patch b/queue-4.9/can-bcm-fix-uaf-of-bcm-op.patch new file mode 100644 index 00000000000..fd02b7cb33c --- /dev/null +++ b/queue-4.9/can-bcm-fix-uaf-of-bcm-op.patch @@ -0,0 +1,66 @@ +From william.xuanziyang@huawei.com Sat Jan 29 12:31:22 2022 +From: Ziyang Xuan +Date: Fri, 28 Jan 2022 14:40:54 +0800 +Subject: can: bcm: fix UAF of bcm op +To: , , , , +Cc: , +Message-ID: <20220128064054.2434068-1-william.xuanziyang@huawei.com> + +From: Ziyang Xuan + +Stopping tasklet and hrtimer rely on the active state of tasklet and +hrtimer sequentially in bcm_remove_op(), the op object will be freed +if they are all unactive. Assume the hrtimer timeout is short, the +hrtimer cb has been excuted after tasklet conditional judgment which +must be false after last round tasklet_kill() and before condition +hrtimer_active(), it is false when execute to hrtimer_active(). Bug +is triggerd, because the stopping action is end and the op object +will be freed, but the tasklet is scheduled. The resources of the op +object will occur UAF bug. + +Move hrtimer_cancel() behind tasklet_kill() and switch 'while () {...}' +to 'do {...} while ()' to fix the op UAF problem. + +Fixes: a06393ed0316 ("can: bcm: fix hrtimer/tasklet termination in bcm op removal") +Reported-by: syzbot+5ca851459ed04c778d1d@syzkaller.appspotmail.com +Cc: stable@vger.kernel.org +Signed-off-by: Ziyang Xuan +Signed-off-by: Greg Kroah-Hartman +--- + net/can/bcm.c | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +--- a/net/can/bcm.c ++++ b/net/can/bcm.c +@@ -761,21 +761,21 @@ static struct bcm_op *bcm_find_op(struct + static void bcm_remove_op(struct bcm_op *op) + { + if (op->tsklet.func) { +- while (test_bit(TASKLET_STATE_SCHED, &op->tsklet.state) || +- test_bit(TASKLET_STATE_RUN, &op->tsklet.state) || +- hrtimer_active(&op->timer)) { +- hrtimer_cancel(&op->timer); ++ do { + tasklet_kill(&op->tsklet); +- } ++ hrtimer_cancel(&op->timer); ++ } while (test_bit(TASKLET_STATE_SCHED, &op->tsklet.state) || ++ test_bit(TASKLET_STATE_RUN, &op->tsklet.state) || ++ hrtimer_active(&op->timer)); + } + + if (op->thrtsklet.func) { +- while (test_bit(TASKLET_STATE_SCHED, &op->thrtsklet.state) || +- test_bit(TASKLET_STATE_RUN, &op->thrtsklet.state) || +- hrtimer_active(&op->thrtimer)) { +- hrtimer_cancel(&op->thrtimer); ++ do { + tasklet_kill(&op->thrtsklet); +- } ++ hrtimer_cancel(&op->thrtimer); ++ } while (test_bit(TASKLET_STATE_SCHED, &op->thrtsklet.state) || ++ test_bit(TASKLET_STATE_RUN, &op->thrtsklet.state) || ++ hrtimer_active(&op->thrtimer)); + } + + if ((op->frames) && (op->frames != &op->sframe)) diff --git a/queue-4.9/series b/queue-4.9/series new file mode 100644 index 00000000000..4db57589629 --- /dev/null +++ b/queue-4.9/series @@ -0,0 +1 @@ +can-bcm-fix-uaf-of-bcm-op.patch