Bug 219408

Summary: btrfs: UAF in __btrfs_free_extra_devids()
Product: File System Reporter: Zhihao Cheng (chengzhihao1)
Component: btrfsAssignee: BTRFS virtual assignee (fs_btrfs)
Status: RESOLVED CODE_FIX    
Severity: normal CC: dsterba
Priority: P3    
Hardware: All   
OS: Linux   
Kernel Version: Subsystem:
Regression: No Bisected commit-id:
Attachments: a.c
diff
mount_1.btrfs
mount_2.btrfs

Description Zhihao Cheng 2024-10-21 13:00:22 UTC
1. Apply diff and compile kernel (CONFIG_BLK_DEV_LOOP_MIN_COUNT=3)
2. gcc -oaa a.c -lpthread
3. ./aa

[  201.643104] alloc ffff88816822f000 ffff88817a9c9c00 1
[  201.654067] alloc ffff88816822a000 ffff88817a9c9c00 2
[  203.677656] aa set bdev loop1 with holder btrfs_fs_type
[  203.689640] aa set bdev loop0 with holder btrfs_fs_type
[  203.733046] aa: prepare to exit
[  203.733454] put file ffff88816822a000 ffff888179106100
[  203.734290] put file ffff88816822f000 ffff88817f34fd00
[  203.735087] aa release, num 2
[  203.735467] BTRFS error (device (efault)): open_ctree failed
[  203.837220] freee file
[  207.684183] bb set bdev loop1 with holder btrfs_fs_type
[  207.686739] Inject err for stale device
[  207.706490] bb set bdev loop0 with holder btrfs_fs_type
[  208.069137] extra device ffff88816822a000
[  208.069705] ==================================================================
[  208.070620] BUG: KASAN: slab-use-after-free in __btrfs_free_extra_devids+0x10b/0x820
[  208.071569] Read of size 8 at addr ffff888179106100 by task bb/1228
[  208.072350] 
[  208.072596] CPU: 0 UID: 0 PID: 1228 Comm: bb Not tainted 6.12.0-rc4-00008-g18ba25746a9d-dirty #958
[  208.073683] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.1-2.fc37 04/01/2014
[  208.074739] Call Trace:
[  208.075852]  <TASK>
[  208.076093]  dump_stack_lvl+0xa3/0x120
[  208.076550]  print_report+0x110/0x8c0
[  208.077018]  ? __btrfs_free_extra_devids+0x10b/0x820
[  208.077613]  kasan_report+0xc0/0x120
[  208.078077]  ? __btrfs_free_extra_devids+0x10b/0x820
[  208.078690]  kasan_check_range+0x2ad/0x2e0
[  208.079197]  __kasan_check_read+0x21/0x30
[  208.079692]  __btrfs_free_extra_devids+0x10b/0x820
[  208.080293]  btrfs_free_extra_devids+0x95/0x1b0
[  208.080871]  ? __pfx_btrfs_free_extra_devids+0x10/0x10
[  208.081500]  open_ctree+0x1ed0/0x5350
[  208.081974]  ? __pfx_open_ctree+0x10/0x10
[  208.082487]  ? __pfx_super_setup_bdi_name+0x10/0x10
[  208.083115]  ? snprintf+0xaa/0xe0
[  208.083544]  ? __pfx_snprintf+0x10/0x10
[  208.084027]  btrfs_get_tree+0x1165/0x1d90
[  208.084543]  ? __link_object+0x1c1/0x270
[  208.085021]  ? __pfx_btrfs_get_tree+0x10/0x10
[  208.085559]  ? kasan_save_track+0x1c/0x40
[  208.086052]  ? kasan_save_alloc_info+0x44/0x70
[  208.086600]  ? __kasan_kmalloc+0xe0/0xf0
[  208.087080]  ? __kmalloc_node_track_caller_noprof+0x33e/0x6e0
[  208.087786]  ? vfs_dup_fs_context+0x75/0x640
[  208.088318]  vfs_get_tree+0x8f/0x390
[  208.088760]  ? security_fs_context_dup+0x4b/0xa0
[  208.089327]  fc_mount+0x1b/0xb0
[  208.089719]  btrfs_get_tree+0x9c4/0x1d90
[  208.090183]  ? __pfx_btrfs_get_tree+0x10/0x10
[  208.090736]  ? vfs_parse_comma_sep+0x1d/0x30
[  208.091268]  ? vfs_parse_monolithic_sep+0x157/0x200
[  208.091851]  ? selinux_capable+0x53/0x90
[  208.092346]  vfs_get_tree+0x8f/0x390
[  208.092783]  ? capable+0x21/0x30
[  208.093197]  path_mount+0x525/0x1c30
[  208.093630]  ? __kasan_slab_free+0x6a/0x90
[  208.094124]  ? __pfx_path_mount+0x10/0x10
[  208.094619]  ? putname+0x130/0x1a0
[  208.095041]  do_mount+0xe7/0x110
[  208.095450]  ? __pfx_do_mount+0x10/0x10
[  208.095923]  ? copy_mount_options+0xe9/0x1b0
[  208.096456]  __x64_sys_mount+0x162/0x230
[  208.096986]  x64_sys_call+0x2d3d/0x4540
[  208.097515]  do_syscall_64+0xa7/0x230
[  208.097986]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
[  208.098545] RIP: 0033:0x7fa98ed1123a
[  208.098976] Code: 48 8b 0d 51 dc 2b 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 49 89 ca b8 a5 00 00 00 0f 05 <488
[  208.101119] RSP: 002b:00007fa98c5ffed8 EFLAGS: 00000286 ORIG_RAX: 00000000000000a5
[  208.101966] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fa98ed1123a
[  208.102786] RDX: 000000000040111c RSI: 0000000000401114 RDI: 0000000000401109
[  208.103624] RBP: 00007fa98c5fff20 R08: 0000000000401103 R09: 00007fa98c600700
[  208.104456] R10: 0000000000000000 R11: 0000000000000286 R12: 00007fa98c600000
[  208.105283] R13: 0000000000000000 R14: 00007ffd31e0bdb0 R15: 00007fa98c6009c0
[  208.106136]  </TASK>
[  208.106371] 
[  208.106564] Allocated by task 1162:
[  208.106984]  kasan_save_stack+0x28/0x60
[  208.107444]  kasan_save_track+0x1c/0x40
[  208.107899]  kasan_save_alloc_info+0x44/0x70
[  208.108401]  __kasan_slab_alloc+0xaf/0xc0
[  208.108875]  kmem_cache_alloc_noprof+0x1d4/0x560
[  208.109422]  alloc_empty_file_noaccount+0x2f/0xf0
[  208.109973]  alloc_file_pseudo_noaccount+0x151/0x230
[  208.110552]  bdev_file_open_by_dev+0xed/0x220
[  208.111071]  bdev_file_open_by_path+0xe5/0x360
[  208.111616]  btrfs_get_bdev_and_sb+0x34/0x3c0
[  208.112141]  open_fs_devices+0x1a2/0x1360
[  208.112635]  btrfs_open_devices+0x91/0xb0
[  208.113117]  btrfs_get_tree+0x447/0x1d90
[  208.113589]  vfs_get_tree+0x8f/0x390
[  208.114035]  fc_mount+0x1b/0xb0
[  208.114418]  btrfs_get_tree+0x9c4/0x1d90
[  208.114895]  vfs_get_tree+0x8f/0x390
[  208.115286]  path_mount+0x525/0x1c30
[  208.115711]  do_mount+0xe7/0x110
[  208.116111]  __x64_sys_mount+0x162/0x230
[  208.116581]  x64_sys_call+0x2d3d/0x4540
[  208.117006]  do_syscall_64+0xa7/0x230
[  208.117471]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
[  208.118078] 
[  208.118296] Freed by task 24:
[  208.118685]  kasan_save_stack+0x28/0x60
[  208.119142]  kasan_save_track+0x1c/0x40
[  208.119610]  kasan_save_free_info+0x43/0x80
[  208.120108]  __kasan_slab_free+0x4f/0x90
[  208.120572]  slab_free_after_rcu_debug+0xf1/0x360
[  208.121126]  rcu_do_batch+0x3d2/0x10f0
[  208.121543]  rcu_core+0x453/0x970
[  208.121951]  rcu_core_si+0x16/0x30
[  208.122374]  handle_softirqs+0x1bf/0x780
[  208.122841]  run_ksoftirqd+0x47/0x70
[  208.123268]  smpboot_thread_fn+0x2f1/0x900
[  208.123757]  kthread+0x313/0x430
[  208.124162]  ret_from_fork+0x59/0x90
[  208.124605]  ret_from_fork_asm+0x1a/0x30
[  208.125088] 
[  208.125359] Last potentially related work creation:
[  208.126003]  kasan_save_stack+0x28/0x60
[  208.126526]  __kasan_record_aux_stack+0xc5/0x120
[  208.127106]  kasan_record_aux_stack_noalloc+0x13/0x20
[  208.127747]  kmem_cache_free+0x317/0x5e0
[  208.128241]  file_free+0x148/0x200
[  208.128661]  __fput+0x4fd/0xbd0
[  208.129044]  ____fput+0x1d/0x30
[  208.129430]  task_work_run+0x15a/0x280
[  208.129897]  syscall_exit_to_user_mode+0x3fe/0x440
[  208.130470]  do_syscall_64+0xbb/0x230
[  208.130864]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
[  208.131462] 
[  208.131660] Second to last potentially related work creation:
[  208.132328]  kasan_save_stack+0x28/0x60
[  208.132846]  __kasan_record_aux_stack+0xc5/0x120
[  208.133395]  kasan_record_aux_stack+0x16/0x30
[  208.133912]  task_work_add+0x98/0x470
[  208.134353]  fput+0x11a/0x230
[  208.134719]  btrfs_close_bdev+0x106/0x290
[  208.135187]  close_fs_devices+0x16b/0x910
[  208.135660]  btrfs_close_devices+0xa4/0x6d0
[  208.136150]  open_ctree+0x1f7/0x5350
[  208.136572]  btrfs_get_tree+0x1165/0x1d90
[  208.137054]  vfs_get_tree+0x8f/0x390
[  208.137490]  fc_mount+0x1b/0xb0
[  208.137865]  btrfs_get_tree+0x9c4/0x1d90
[  208.138327]  vfs_get_tree+0x8f/0x390
[  208.138753]  path_mount+0x525/0x1c30
[  208.139176]  do_mount+0xe7/0x110
[  208.139565]  __x64_sys_mount+0x162/0x230
[  208.140044]  x64_sys_call+0x2d3d/0x4540
[  208.140505]  do_syscall_64+0xa7/0x230
[  208.140951]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
[  208.141548] 
[  208.141745] The buggy address belongs to the object at ffff888179106100
[  208.141745]  which belongs to the cache filp of size 184
[  208.143131] The buggy address is located 0 bytes inside of
[  208.143131]  freed 184-byte region [ffff888179106100, ffff8881791061b8)
[  208.144513] 
[  208.144707] The buggy address belongs to the physical page:
[  208.145362] page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x179106
[  208.146303] ksm flags: 0x17ffffc0000000(node=0|zone=2|lastcpupid=0x1fffff)
[  208.147100] page_type: f5(slab)
[  208.147489] raw: 0017ffffc0000000 ffff8881008c6000 ffffea0005e67280 dead000000000003
[  208.148394] raw: 0000000000000000 0000000000100010 00000001f5000000 0000000000000000
[  208.149285] page dumped because: kasan: bad access detected
[  208.149936] 
[  208.150138] Memory state around the buggy address:
[  208.150745]  ffff888179106000: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[  208.151605]  ffff888179106080: fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc fc
[  208.152412] >ffff888179106100: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[  208.153238]                    ^
[  208.153627]  ffff888179106180: fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc fc
[  208.154459]  ffff888179106200: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[  208.155286] ==================================================================
Comment 1 Zhihao Cheng 2024-10-21 13:00:50 UTC
Created attachment 307027 [details]
a.c
Comment 2 Zhihao Cheng 2024-10-21 13:01:02 UTC
Created attachment 307028 [details]
diff
Comment 3 Zhihao Cheng 2024-10-21 13:01:27 UTC
Created attachment 307029 [details]
mount_1.btrfs
Comment 4 Zhihao Cheng 2024-10-21 13:02:25 UTC
Created attachment 307030 [details]
mount_2.btrfs
Comment 5 David Sterba 2024-10-25 18:50:12 UTC
Thanks for the report and reproducer, fixed in for-next by https://lore.kernel.org/linux-btrfs/20241021140215.2948551-1-chengzhihao@huaweicloud.com/ .