Bug 23507 - brd: fetching the page concurrently by discard trigger BUG_ON()
Summary: brd: fetching the page concurrently by discard trigger BUG_ON()
Status: NEW
Alias: None
Product: ANCK 6.6 Dev
Classification: ANCK
Component: drivers (show other bugs) drivers
Version: 6.6.88-4
Hardware: All Linux
: P3-Medium S2-major
Target Milestone: ---
Assignee: GuixinLiu
QA Contact: shuming
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2025-08-11 16:56 UTC by shineway
Modified: 2025-08-11 17:21 UTC (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description shineway 2025-08-11 16:56:00 UTC
Description of problem:
brd: fetching the page concurrently by discard trigger BUG_ON().


[  145.694919] ------------[ cut here ]------------
[  145.694924] kernel BUG at drivers/block/brd.c:63!
[  145.694957] invalid opcode: 0000 [#1] PREEMPT SMP PTI
[  145.694962] CPU: 20 PID: 4438 Comm: fio Kdump: loaded Tainted: G            E      6.6.88-anolis-devel-6.6 #1
[  145.694966] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014
[  145.694968] RIP: 0010:copy_to_brd+0x1c8/0x1d0 [brd]
[  145.694975] Code: 01 65 ff 0d 42 0d 43 3f 0f 85 2c ff ff ff 0f 1f 44 00 00 e9 22 ff ff ff 89 e8 41 0f b7 54 06 fe 66 89 54 01 fe e9 f2 fe ff ff <0f> 0b 0f 0b 90 0f 1f 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90
[  145.694978] RSP: 0018:ffffb100c10efb10 EFLAGS: 00010202
[  145.694982] RAX: ffffe8f305c82a40 RBX: ffff947ecc04cf80 RCX: 0000000000000000
[  145.694983] RDX: 0000000000000028 RSI: ffff947eec43cdb0 RDI: 00000000000005a8
[  145.694985] RBP: 0000000000001000 R08: 0000000000001000 R09: 0000000000000000
[  145.694987] R10: 0000000000001000 R11: 0000000000000000 R12: 0000000000001000
[  145.694989] R13: 0000000000000000 R14: ffff947f81343000 R15: 0000000000002d40
[  145.694994] FS:  00007f0f567fc6c0(0000) GS:ffff948066a00000(0000) knlGS:0000000000000000
[  145.694996] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  145.694998] CR2: 00007fbca28313e8 CR3: 000000014a296002 CR4: 0000000000770ee0
[  145.695000] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[  145.695001] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[  145.695003] PKRU: 55555554
[  145.695005] Call Trace:
[  145.695008]  <TASK>
[  145.695013]  brd_submit_bio+0x2c6/0x3b0 [brd]
[  145.695019]  __submit_bio+0x84/0x110
[  145.695034]  __submit_bio_noacct+0x7e/0x210
[  145.695037]  submit_bio_noacct+0x1c1/0x630
[  145.695040]  ? __pfx_autoremove_wake_function+0x10/0x10
[  145.695045]  __blkdev_direct_IO_async+0x18b/0x1c0
[  145.695050]  blkdev_write_iter+0x1af/0x2f0
[  145.695052]  aio_write+0x11b/0x240
[  145.695058]  ? __check_object_size.part.0+0x5c/0x120
[  145.695062]  ? _copy_to_user+0x26/0x40
[  145.695069]  ? kmem_cache_alloc+0x171/0x370
[  145.695073]  ? fget+0x7d/0xb0
[  145.695078]  ? io_submit_one+0xe2/0x370
[  145.695080]  io_submit_one+0xe2/0x370
[  145.695083]  __x64_sys_io_submit+0x81/0x170
[  145.695086]  ? do_io_getevents+0x89/0xe0
[  145.695088]  ? __x64_sys_io_getevents+0x5c/0xd0
[  145.695090]  do_syscall_64+0x38/0x80
[  145.695097]  entry_SYSCALL_64_after_hwframe+0x78/0xe2
[  145.695105] RIP: 0033:0x7f0fdc70733d
[  145.695108] Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d b3 7a 12 00 f7 d8 64 89 01 48
[  145.695110] RSP: 002b:00007f0f567fba78 EFLAGS: 00000246 ORIG_RAX: 00000000000000d1
[  145.695112] RAX: ffffffffffffffda RBX: 00007f0f567fc638 RCX: 00007f0fdc70733d
[  145.695116] RDX: 00007f0f40001020 RSI: 0000000000000001 RDI: 00007f0fc4344000
[  145.695118] RBP: 00007f0fc4344000 R08: 0000000000000000 R09: 0000000000000000
[  145.695119] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000001
[  145.695121] R13: 0000000000000000 R14: 00007f0f40001020 R15: 00007f0f40001120
[  145.695125]  </TASK>
[  145.695125] Modules linked in: brd(E) overlay(E) rfkill(E) ipt_REJECT(E) nf_reject_ipv4(E) xt_cgroup(E) nft_compat(E) nf_tables(E) intel_rapl_msr(E) intel_rapl_common(E) isst_if_mbox_msr(E) isst_if_common(E) skx_edac_common(E) nfit(E) sunrpc(E) kvm_intel(E) binfmt_misc(E) kvm(E) irqbypass(E) rapl(E) joydev(E) virtio_net(E) mousedev(E) net_failover(E) failover(E) psmouse(E) i2c_piix4(E) virtio_balloon(E) pcspkr(E) fuse(E) loop(E) nfnetlink(E) xfs(E) libcrc32c(E) sd_mod(E) t10_pi(E) sr_mod(E) crc64_rocksoft_generic(E) cirrus(E) cdrom(E) crc64_rocksoft(E) crct10dif_pclmul(E) drm_shmem_helper(E) crc64(E) ata_generic(E) crc32_pclmul(E) drm_kms_helper(E) crc32c_intel(E) ata_piix(E) virtio_scsi(E) ghash_clmulni_intel(E) drm(E) libata(E) serio_raw(E) dm_mirror(E) dm_region_hash(E) dm_log(E) dm_multipath(E) dm_mod(E) ecryptfs(E)



Version-Release number of selected component (if applicable):
[~]# uname -a
Linux Anolis 6.6.88-anolis-devel-6.6 #1 SMP PREEMPT_DYNAMIC Mon Aug 11 10:52:02 CST 2025 x86_64 x86_64 x86_64 GNU/Linux



How reproducible:
Fio 32 threads 4k randomly write to memory disk:
[~]# fio -filename=/dev/ram0 -direct=1 -thread -size=512M -numjobs=32 -iodepth=32 -rw=randwrite -bs=4k -ioengine=libaio -name=libaio_randwrite_4k --runtime=60000 --time_based

Discard Request concurrently:
[~]# while true ;do blkdiscard /dev/ram0; sleep 0.1; done


Actual results:
trigger BUG_ON()

Expected results:
DO NOT trigger BUG_ON()

Additional info:
Comment 1 shineway 2025-08-11 16:58:09 UTC
Currently, after fetching the page by xa_load() in IO path, there is no
protection and page can be freed concurrently by discard:

cpu0
brd_submit_bio
 brd_do_bvec
  page = brd_lookup_page
                          cpu1
                          brd_submit_bio
                           brd_do_discard
                            page = __xa_erase()
                            __free_page()
  // page UAF

Fix the problem by protecting page with rcu.

A series of patches need to be merged, as follows:

NO	commit ID					subject	description
1	7d8d35791b1b87a503ebe1f2f48407ee05dbaf5e	brd: Remove use of page->index	optimize
2	75d99aa279561fc6d91afec8bdd1b56548f860a2	brd: pass a bvec pointer to brd_do_bvec	optimize
3	857aba38b56a0d8fa868706c57053dcd4282e436	brd: remove the sector variable in brd_submit_bio	optimize
4	95a375a3bed3b8734059351ba046a6fabdbde485	brd: use bvec_kmap_local in brd_do_bvec	optimize
5	3185444f0504ca8ff54e2a7275f1ff60a6a6cf0c	brd: split I/O at page boundaries	optimize
6	53ec1abce79c986dc59e59d0c60d00088bcdf32a	brd: use memcpy_{to,from]_page in brd_rw_bvec	optimize
7	0e8acffc1be10d53e909b3aa43831d6c2d25a579	brd: protect page with rcu	Fixes: 9ead7efc6f3f
8	d4099f8893b057ad7e8d61df76bdeaf807ebd679	brd: fix aligned_sector from brd_do_discard()	Fixes: 9ead7efc6f3f
9	a26a339a654b9403f0ee1004f1db4c2b2a355460	brd: fix discard end sector	Fixes: 9ead7efc6f3f
10	bbcacab2e8ee373eb8f4bc613912e7c203deb820	brd: avoid extra xarray lookups on first write	optimize
11	0d519bb0de3bf0ac9e6f401d4910fc119062d7be	brd: fix sleeping function called from invalid context in brd_insert_page()	Fixes: bbcacab2e8ee
Comment 2 小龙 admin 2025-08-11 17:21:04 UTC
The PR Link: https://gitee.com/anolis/cloud-kernel/pulls/5612