From: Greg Kroah-Hartman Date: Mon, 14 Oct 2024 13:10:28 +0000 (+0200) Subject: 5.15-stable patches X-Git-Tag: v5.10.227~21 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=998d8b4ba5b41f550ee60d9c6caba23d40ff1c7b;p=thirdparty%2Fkernel%2Fstable-queue.git 5.15-stable patches added patches: block-bfq-fix-uaf-for-accessing-waker_bfqq-after-splitting.patch --- diff --git a/queue-5.15/block-bfq-fix-uaf-for-accessing-waker_bfqq-after-splitting.patch b/queue-5.15/block-bfq-fix-uaf-for-accessing-waker_bfqq-after-splitting.patch new file mode 100644 index 00000000000..a6d4cf45c40 --- /dev/null +++ b/queue-5.15/block-bfq-fix-uaf-for-accessing-waker_bfqq-after-splitting.patch @@ -0,0 +1,90 @@ +From 1ba0403ac6447f2d63914fb760c44a3b19c44eaf Mon Sep 17 00:00:00 2001 +From: Yu Kuai +Date: Mon, 9 Sep 2024 21:41:48 +0800 +Subject: block, bfq: fix uaf for accessing waker_bfqq after splitting + +From: Yu Kuai + +commit 1ba0403ac6447f2d63914fb760c44a3b19c44eaf upstream. + +After commit 42c306ed7233 ("block, bfq: don't break merge chain in +bfq_split_bfqq()"), if the current procress is the last holder of bfqq, +the bfqq can be freed after bfq_split_bfqq(). Hence recored the bfqq and +then access bfqq->waker_bfqq may trigger UAF. What's more, the waker_bfqq +may in the merge chain of bfqq, hence just recored waker_bfqq is still +not safe. + +Fix the problem by adding a helper bfq_waker_bfqq() to check if +bfqq->waker_bfqq is in the merge chain, and current procress is the only +holder. + +Fixes: 42c306ed7233 ("block, bfq: don't break merge chain in bfq_split_bfqq()") +Signed-off-by: Yu Kuai +Link: https://lore.kernel.org/r/20240909134154.954924-2-yukuai1@huaweicloud.com +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + block/bfq-iosched.c | 31 ++++++++++++++++++++++++++++--- + 1 file changed, 28 insertions(+), 3 deletions(-) + +--- a/block/bfq-iosched.c ++++ b/block/bfq-iosched.c +@@ -6568,6 +6568,31 @@ static void bfq_prepare_request(struct r + rq->elv.priv[0] = rq->elv.priv[1] = NULL; + } + ++static struct bfq_queue *bfq_waker_bfqq(struct bfq_queue *bfqq) ++{ ++ struct bfq_queue *new_bfqq = bfqq->new_bfqq; ++ struct bfq_queue *waker_bfqq = bfqq->waker_bfqq; ++ ++ if (!waker_bfqq) ++ return NULL; ++ ++ while (new_bfqq) { ++ if (new_bfqq == waker_bfqq) { ++ /* ++ * If waker_bfqq is in the merge chain, and current ++ * is the only procress. ++ */ ++ if (bfqq_process_refs(waker_bfqq) == 1) ++ return NULL; ++ break; ++ } ++ ++ new_bfqq = new_bfqq->new_bfqq; ++ } ++ ++ return waker_bfqq; ++} ++ + /* + * If needed, init rq, allocate bfq data structures associated with + * rq, and increment reference counters in the destination bfq_queue +@@ -6628,7 +6653,7 @@ static struct bfq_queue *bfq_init_rq(str + /* If the queue was seeky for too long, break it apart. */ + if (bfq_bfqq_coop(bfqq) && bfq_bfqq_split_coop(bfqq) && + !bic->stably_merged) { +- struct bfq_queue *old_bfqq = bfqq; ++ struct bfq_queue *waker_bfqq = bfq_waker_bfqq(bfqq); + + /* Update bic before losing reference to bfqq */ + if (bfq_bfqq_in_large_burst(bfqq)) +@@ -6647,7 +6672,7 @@ static struct bfq_queue *bfq_init_rq(str + bfqq_already_existing = true; + + if (!bfqq_already_existing) { +- bfqq->waker_bfqq = old_bfqq->waker_bfqq; ++ bfqq->waker_bfqq = waker_bfqq; + bfqq->tentative_waker_bfqq = NULL; + + /* +@@ -6657,7 +6682,7 @@ static struct bfq_queue *bfq_init_rq(str + * woken_list of the waker. See + * bfq_check_waker for details. + */ +- if (bfqq->waker_bfqq) ++ if (waker_bfqq) + hlist_add_head(&bfqq->woken_list_node, + &bfqq->waker_bfqq->woken_list); + } diff --git a/queue-5.15/series b/queue-5.15/series index a1ae9879344..802d8e57ec6 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -683,3 +683,4 @@ net-dsa-lan9303-ensure-chip-reset-and-wait-for-ready-status.patch mptcp-pm-do-not-remove-closing-subflows.patch nouveau-dmem-fix-vulnerability-in-migrate_to_ram-upon-copy-error.patch kthread-unpark-only-parked-kthread.patch +block-bfq-fix-uaf-for-accessing-waker_bfqq-after-splitting.patch