]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 14 Oct 2024 13:10:28 +0000 (15:10 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 14 Oct 2024 13:10:28 +0000 (15:10 +0200)
added patches:
block-bfq-fix-uaf-for-accessing-waker_bfqq-after-splitting.patch

queue-5.15/block-bfq-fix-uaf-for-accessing-waker_bfqq-after-splitting.patch [new file with mode: 0644]
queue-5.15/series

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 (file)
index 0000000..a6d4cf4
--- /dev/null
@@ -0,0 +1,90 @@
+From 1ba0403ac6447f2d63914fb760c44a3b19c44eaf Mon Sep 17 00:00:00 2001
+From: Yu Kuai <yukuai3@huawei.com>
+Date: Mon, 9 Sep 2024 21:41:48 +0800
+Subject: block, bfq: fix uaf for accessing waker_bfqq after splitting
+
+From: Yu Kuai <yukuai3@huawei.com>
+
+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 <yukuai3@huawei.com>
+Link: https://lore.kernel.org/r/20240909134154.954924-2-yukuai1@huaweicloud.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
+                       }
index a1ae9879344e9a82ea30f6d550a51fbab63874ba..802d8e57ec67cb99e793ca4089a871074d493882 100644 (file)
@@ -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