dump_stack_lvl+0x43/0x60 print_report+0xcf/0x640 kasan_report+0xa6/0xd0 __blk_rq_map_sg+0x18f/0x7c0 virtblk_prep_rq.isra.0+0x215/0x6a0 [virtio_blk 19a65eeee9ae6fcf02edfad39bb9ddee07dcdaff] virtio_queue_rqs+0xc4/0x310 [virtio_blk 19a65eeee9ae6fcf02edfad39bb9ddee07dcdaff] blk_mq_flush_plug_list.part.0+0x780/0x860 __blk_flush_plug+0x1ba/0x220 blk_finish_plug+0x3b/0x60 submit_initial_group_read+0x10a/0x290 [btrfs e57987a360bed82fe8756dcd3e0de5406ccfe965] flush_scrub_stripes+0x38e/0x430 [btrfs e57987a360bed82fe8756dcd3e0de5406ccfe965] scrub_stripe+0x82a/0xae0 [btrfs e57987a360bed82fe8756dcd3e0de5406ccfe965] scrub_chunk+0x178/0x200 [btrfs e57987a360bed82fe8756dcd3e0de5406ccfe965] scrub_enumerate_chunks+0x4bc/0xa30 [btrfs e57987a360bed82fe8756dcd3e0de5406ccfe965] btrfs_scrub_dev+0x398/0x810 [btrfs e57987a360bed82fe8756dcd3e0de5406ccfe965] btrfs_ioctl+0x4b9/0x3020 [btrfs e57987a360bed82fe8756dcd3e0de5406ccfe965] __x64_sys_ioctl+0xbd/0x100 do_syscall_64+0x5d/0xe0 entry_SYSCALL_64_after_hwframe+0x63/0x6b RIP: 0033:0x7f47e5e0952b - Crash, mostly due to above use-after-free [CAUSE] The converted fs has the following data chunk layout: item 2 key (FIRST_CHUNK_TREE CHUNK_ITEM 2214658048) itemoff 16025 itemsize 80 length 86016 owner 2 stripe_len 65536 type DATA|single For above logical bytenr 2214744064, it's at the chunk end (2214658048 + 86016 = 2214744064). This means btrfs_submit_bio() would split the bio, and trigger endio function for both of the two halves. However scrub_submit_initial_read() would only expect the endio function to be called once, not any more. This means the first endio function would already free the bbio::bio, leaving the bvec freed, thus the 2nd endio call would lead to use-after-free. [FIX] - Make sure scrub_read_endio() only updates bits in its range Since we may read less than 64K at the end of the chunk, we should not touch the bits beyond chunk boundary. - Make sure scrub_submit_initial_read() only to read the chunk range This is done by calculating the real number of sectors we need to read, and add sector-by-sector to the bio. Thankfully the scrub read repair path won't need extra fixes: - scrub_stripe_submit_repair_read() With above fixes, we won't update error bit for range beyond chunk, thus scrub_stripe_submit_repair_read() should never submit any read beyond the chunk. "> dump_stack_lvl+0x43/0x60,print_report+0xcf/0x640 kasan_report+0xa6/0xd0,__blk_rq_map_sg+0x18f/0x7c0 virtblk_prep_rq.isra.0+0x215/0x6a0,[virtio_blk 19a65eeee9ae6fcf02edfad39bb9ddee07dcdaff],virtio_queue_rqs+0xc4/0x310 [virtio_blk,19a65eeee9ae6fcf02edfad39bb9ddee07dcdaff] blk_mq_flush_plug_list.part.0+0x780/0x860,__blk_flush_plug+0x1ba/0x220 blk_finish_plug+0x3b/0x60,submit_initial_group_read+0x10a/0x290,[btrfs e57987a360bed82fe8756dcd3e0de5406ccfe965] flush_scrub_stripes+0x38e/0x430,[btrfs e57987a360bed82fe8756dcd3e0de5406ccfe965],scrub_stripe+0x82a/0xae0 [btrfs,e57987a360bed82fe8756dcd3e0de5406ccfe965] scrub_chunk+0x178/0x200,[btrfs e57987a360bed82fe8756dcd3e0de5406ccfe965] scrub_enumerate_chunks+0x4bc/0xa30,[btrfs e57987a360bed82fe8756dcd3e0de5406ccfe965],btrfs_scrub_dev+0x398/0x810 [btrfs,e57987a360bed82fe8756dcd3e0de5406ccfe965] btrfs_ioctl+0x4b9/0x3020,[btrfs e57987a360bed82fe8756dcd3e0de5406ccfe965],__x64_sys_ioctl+0xbd/0x100 do_syscall_64+0x5d/0xe0,entry_SYSCALL_64_after_hwframe+0x63/0x6b,RIP: 0033:0x7f47e5e0952b,-,Crash,,mostly,due,to,above,use-after-free [CAUSE],The,converted,fs,has,the,following,data,chunk,layout:,item,2 key,(FIRST_CHUNK_TREE,CHUNK_ITEM,2214658048),itemoff,16025,itemsize,80 length,86016,owner,2,stripe_len,65536,type,DATA|single,For,above logical,bytenr,2214744064,,it's,at,the,chunk,end,(2214658048,+,86016,= 2214744064).,This,means,btrfs_submit_bio(),would,split,the,bio,,and trigger,endio,function,for,both,of,the,two,halves.,However scrub_submit_initial_read(),would,only,expect,the,endio,function,to,be called,once,,not,any,more.,This,means,the,first,endio,function,would already,free,the,bbio::bio,,leaving,the,bvec,freed,,thus,the,2nd,endio call,would,lead,to,use-after-free.,[FIX],-,Make,sure scrub_read_endio(),only,updates,bits,in,its,range,Since,we,may,read less,than,64K,at,the,end,of,the,chunk,,we,should,not,touch,the,bits beyond,chunk,boundary.,-,Make,sure,scrub_submit_initial_read(),only,to read,the,chunk,range,This,is,done,by,calculating,the,real,number,of sectors,we,need,to,read,,and,add,sector-by-sector,to,the,bio. Thankfully,the,scrub,read,repair,path,won't,need,extra,fixes:,- scrub_stripe_submit_repair_read(),With,above,fixes,,we,won't,update error,bit,for,range,beyond,chunk,,thus scrub_stripe_submit_repair_read(),should,never,submit,any,read,beyond the,chunk. ">
![]() |
Home ▼ Bookkeeping
Online ▼ Security
Audits ▼
Managed
DNS ▼
About
Order
FAQ
Acceptable Use Policy
Dynamic DNS Clients
Configure Domains Dyanmic DNS Update Password Network
Monitor ▼
Enterprise Package
Advanced Package
Standard Package
Free Trial
FAQ
Price/Feature Summary
Order/Renew
Examples
Configure/Status Alert Profiles | ||
CVE ID: | CVE-2024-26616 |
Description: | In the Linux kernel, the following vulnerability has been resolved:
btrfs: scrub: avoid use-after-free when chunk length is not 64K
aligned [BUG] There is a bug report that, on a ext4-converted btrfs,
scrub leads to various problems, including: - "unable to find chunk
map" errors BTRFS info (device vdb): scrub: started on devid 1 BTRFS
critical (device vdb): unable to find chunk map for logical 2214744064
length 4096 BTRFS critical (device vdb): unable to find chunk map for
logical 2214744064 length 45056 This would lead to unrepariable
errors. - Use-after-free KASAN reports:
==================================================================
BUG: KASAN: slab-use-after-free in __blk_rq_map_sg+0x18f/0x7c0 Read of
size 8 at addr ffff8881013c9040 by task btrfs/909 CPU: 0 PID: 909
Comm: btrfs Not tainted 6.7.0-x64v3-dbg #11
c50636e9419a8354555555245df535e380563b2b Hardware name: QEMU Standard
PC (Q35 + ICH9, 2009), BIOS 2023.11-2 12/24/2023 Call Trace: |
Test IDs: | None available |
Cross References: |
Common Vulnerability Exposure (CVE) ID: CVE-2024-26616 https://git.kernel.org/stable/c/34de0f04684ec00c093a0455648be055f0e8e24f https://git.kernel.org/stable/c/34de0f04684ec00c093a0455648be055f0e8e24f https://git.kernel.org/stable/c/642b9c520ef2f104277ad1f902f8526edbe087fb https://git.kernel.org/stable/c/642b9c520ef2f104277ad1f902f8526edbe087fb https://git.kernel.org/stable/c/f546c4282673497a06ecb6190b50ae7f6c85b02f https://git.kernel.org/stable/c/f546c4282673497a06ecb6190b50ae7f6c85b02f |