CVE-2024-47706: block, bfq: fix possible UAF for bfqq->bic with merge chain
In the Linux kernel, the following vulnerability has been resolved:
block, bfq: fix possible UAF for bfqq->bic with merge chain
1) initial state, three tasks:
Process 1 Process 2 Process 3 (BIC1) (BIC2) (BIC3) | Λ | Λ | Λ | | | | | | V | V | V | bfqq1 bfqq2 bfqq3 process ref: 1 1 1
2) bfqq1 merged to bfqq2:
Process 1 Process 2 Process 3 (BIC1) (BIC2) (BIC3) | | | Λ \--------------\| | | V V | bfqq1--------->bfqq2 bfqq3 process ref: 0 2 1
3) bfqq2 merged to bfqq3:
Process 1 Process 2 Process 3 (BIC1) (BIC2) (BIC3) here -> Λ | | \--------------\ \-------------\| V V bfqq1--------->bfqq2---------->bfqq3 process ref: 0 1 3
In this case, IO from Process 1 will get bfqq2 from BIC1 first, and then get bfqq3 through merge chain, and finially handle IO by bfqq3. Howerver, current code will think bfqq2 is owned by BIC1, like initial state, and set bfqq2->bic to BIC1.
bfqinsertrequest -> by Process 1 bfqq = bfqinitrq(rq) bfqq = bfqgetbfqqhandlesplit bfqq = bictobfqq -> get bfqq2 from BIC1 bfqq->ref++ rq->elv.priv[0] = bic rq->elv.priv[1] = bfqq if (bfqqprocessrefs(bfqq) == 1) bfqq->bic = bic -> record BIC1 to bfqq2
bfqinsertrequest newbfqq = bfqsetupcooperator -> get bfqq3 from bfqq2->newbfqq bfqqrequestfreed(bfqq) newbfqq->ref++ rq->elv.priv[1] = newbfqq -> handle IO by bfqq3
Fix the problem by checking bfqq is from merge chain fist. And this might fix a following problem reported by our syzkaller(unreproducible):
================================================================== BUG: KASAN: slab-use-after-free in bfqdoearlystablemerge block/bfq-iosched.c:5692 [inline] BUG: KASAN: slab-use-after-free in bfqdoorschedstablemerge block/bfq-iosched.c:5805 [inline] BUG: KASAN: slab-use-after-free in bfqgetqueue+0x25b0/0x2610 block/bfq-iosched.c:5889 Write of size 1 at addr ffff888123839eb8 by task kworker/0:1H/18595
CPU: 0 PID: 18595 Comm: kworker/0:1H Tainted: G L 6.6.0-07439-gba2303cacfda #6 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014 Workqueue: kblockd blkmqrequeuework Call Trace: <TASK> dumpstack lib/dumpstack.c:88 [inline] dumpstacklvl+0x91/0xf0 lib/dumpstack.c:106 printaddressdescription mm/kasan/report.c:364 [inline] printreport+0x10d/0x610 mm/kasan/report.c:475 kasanreport+0x8e/0xc0 mm/kasan/report.c:588 bfqdoearlystablemerge block/bfq-iosched.c:5692 [inline] bfqdoorschedstablemerge block/bfq-iosched.c:5805 [inline] bfqgetqueue+0x25b0/0x2610 block/bfq-iosched.c:5889 bfqgetbfqqhandlesplit+0x169/0x5d0 block/bfq-iosched.c:6757 bfqinitrq block/bfq-iosched.c:6876 [inline] bfqinsertrequest block/bfq-iosched.c:6254 [inline] bfqinsertrequests+0x1112/0x5cf0 block/bfq-iosched.c:6304 blkmqinsertrequest+0x290/0x8d0 block/blk-mq.c:2593 blkmqrequeuework+0x6bc/0xa70 block/blk-mq.c:1502 processonework kernel/workqueue.c:2627 [inline] processscheduledworks+0x432/0x13f0 kernel/workqueue.c:2700 workerthread+0x6f2/0x1160 kernel/workqueue.c:2781 kthread+0x33c/0x440 kernel/kthread.c:388 retfromfork+0x4d/0x80 arch/x86/kernel/process.c:147 retfromforkasm+0x1b/0x30 arch/x86/entry/entry64.S:305 </TASK>
Allocated by task 20776: kasansavestack+0x20/0x40 mm/kasan/common.c:45 kasansettrack+0x25/0x30 mm/kasan/common.c:52 kasanslaballoc+0x87/0x90 mm/kasan/common.c:328 kasanslaballoc include/linux/kasan.h:188 [inline] slabpostallochook mm/slab.h:763 [inline] slaballocnode mm/slub.c:3458 [inline] kmemcacheallocnode+0x1a4/0x6f0 mm/slub.c:3503 ioccreateicq block/blk-ioc.c:370 [inline] ---truncated---
Other sources
In the Linux kernel, the following vulnerability has been resolved:
block, bfq: fix possible UAF for bfqq->bic with merge chain
1) initial state, three tasks:
Process 1 Process 2 Process 3 (BIC1) (BIC2) (BIC3) | Λ | Λ | Λ | | | | | | V | V | V | bfqq1 bfqq2 bfqq3 process ref: 1 1 1
2) bfqq1 merged to bfqq2:
Process 1 Process 2 Process 3 (BIC1) (BIC2) (BIC3) | | | Λ \--------------\| | | V V | bfqq1--------->bfqq2 bfqq3 process ref: 0 2 1
3) bfqq2 merged to bfqq3:
Process 1 Process 2 Process 3 (BIC1) (BIC2) (BIC3) here -> Λ | | \--------------\ \-------------\| V V bfqq1--------->bfqq2---------->bfqq3 process ref: 0 1 3
In this case, IO from Process 1 will get bfqq2 from BIC1 first, and then get bfqq3 through merge chain, and finially handle IO by bfqq3. Howerver, current code will think bfqq2 is owned by BIC1, like initial state, and set bfqq2->bic to BIC1.
bfqinsertrequest -> by Process 1 bfqq = bfqinitrq(rq) bfqq = bfqgetbfqqhandlesplit bfqq = bictobfqq -> get bfqq2 from BIC1 bfqq->ref++ rq->elv.priv[0] = bic rq->elv.priv[1] = bfqq if (bfqqprocessrefs(bfqq) == 1) bfqq->bic = bic -> record BIC1 to bfqq2
bfqinsertrequest newbfqq = bfqsetupcooperator -> get bfqq3 from bfqq2->newbfqq bfqqrequestfreed(bfqq) newbfqq->ref++ rq->elv.priv[1] = newbfqq -> handle IO by bfqq3
Fix the problem by checking bfqq is from merge chain fist. And this might fix a following problem reported by our syzkaller(unreproducible):
================================================================== BUG: KASAN: slab-use-after-free in bfqdoearlystablemerge block/bfq-iosched.c:5692 [inline] BUG: KASAN: slab-use-after-free in bfqdoorschedstablemerge block/bfq-iosched.c:5805 [inline] BUG: KASAN: slab-use-after-free in bfqgetqueue+0x25b0/0x2610 block/bfq-iosched.c:5889 Write of size 1 at addr ffff888123839eb8 by task kworker/0:1H/18595
CPU: 0 PID: 18595 Comm: kworker/0:1H Tainted: G L 6.6.0-07439-gba2303cacfda #6 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014 Workqueue: kblockd blkmqrequeuework Call Trace: <TASK> dumpstack lib/dumpstack.c:88 [inline] dumpstacklvl+0x91/0xf0 lib/dumpstack.c:106 printaddressdescription mm/kasan/report.c:364 [inline] printreport+0x10d/0x610 mm/kasan/report.c:475 kasanreport+0x8e/0xc0 mm/kasan/report.c:588 bfqdoearlystablemerge block/bfq-iosched.c:5692 [inline] bfqdoorschedstablemerge block/bfq-iosched.c:5805 [inline] bfqgetqueue+0x25b0/0x2610 block/bfq-iosched.c:5889 bfqgetbfqqhandlesplit+0x169/0x5d0 block/bfq-iosched.c:6757 bfqinitrq block/bfq-iosched.c:6876 [inline] bfqinsertrequest block/bfq-iosched.c:6254 [inline] bfqinsertrequests+0x1112/0x5cf0 block/bfq-iosched.c:6304 blkmqinsertrequest+0x290/0x8d0 block/blk-mq.c:2593 blkmqrequeuework+0x6bc/0xa70 block/blk-mq.c:1502 processonework kernel/workqueue.c:2627 [inline] processscheduledworks+0x432/0x13f0 kernel/workqueue.c:2700 workerthread+0x6f2/0x1160 kernel/workqueue.c:2781 kthread+0x33c/0x440 kernel/kthread.c:388 retfromfork+0x4d/0x80 arch/x86/kernel/process.c:147 retfromforkasm+0x1b/0x30 arch/x86/entry/entry64.S:305 </TASK>
Allocated by task 20776: kasansavestack+0x20/0x40 mm/kasan/common.c:45 kasansettrack+0x25/0x30 mm/kasan/common.c:52 kasanslaballoc+0x87/0x90 mm/kasan/common.c:328 kasanslaballoc include/linux/kasan.h:188 [inline] slabpostallochook mm/slab.h:763 [inline] slaballocnode mm/slub.c:3458 [inline] kmemcacheallocnode+0x1a4/0x6f0 mm/slub.c:3503 ioccreateicq block/blk-ioc.c:370 [inline] ---truncated---
— NVD
This CVE was automatically created from a reference found in an email or other text. If you are reading this, then this CVE entry is probably erroneous, since this text should be replaced by the official CVE description automatically.
— Launchpad
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
debian/linuxto a version that resolves this vulnerability.Fixed in 5.10.234-1Fixed in 6.1.129-1Fixed in 6.1.135-1Fixed in 6.12.25-1Fixed in 6.12.27-1 - Upgrade
Upgrade
debian/linux-6.1to a version that resolves this vulnerability.Fixed in 6.1.129-1~deb11u1 - Configuration
Apply the upstream fix described in: "block, bfq: fix possible UAF for bfqq->bic with merge chain" / "Fix the problem by checking bfqq is from merge chain fist." Ensure the code does not incorrectly treat bfqq2 as owned by BIC1 after bfqq2 has been merged into bfqq3; update the bfq logic in bfq_get_queue path so bfqq->bic is set only when bfqq originates from the proper merge chain.
Linux kernel BFQ (block/bfq-iosched.c) bfqq->bic assignment during merge-chain handling = Check that bfqq is from the merge chain first; only set bfqq->bic based on the correct merge-chain owner (avoid setting bfqq2->bic to BIC1 in the merge-chain scenario).
Event History
Frequently Asked Questions
What is the severity of CVE-2024-47706?
CVE-2024-47706 is classified as a medium severity vulnerability in the Linux kernel.
Which versions of the Linux kernel are affected by CVE-2024-47706?
CVE-2024-47706 affects Linux kernel versions from 4.12 to 6.6.54, including several specific version ranges.
How do I fix CVE-2024-47706?
To fix CVE-2024-47706, update your Linux kernel to a version that is not affected, such as 6.1.123-1 or later.
What type of vulnerability is CVE-2024-47706?
CVE-2024-47706 is a use-after-free (UAF) vulnerability that affects the block layer in the Linux kernel.
Is there a workaround for CVE-2024-47706?
Currently, there are no specific workarounds for CVE-2024-47706 other than applying the necessary kernel updates.