loop: serialize backing file swaps with sysfs readers#993
Open
blktests-ci[bot] wants to merge 1 commit into
Open
loop: serialize backing file swaps with sysfs readers#993blktests-ci[bot] wants to merge 1 commit into
blktests-ci[bot] wants to merge 1 commit into
Conversation
The backing_file sysfs attribute formats lo->lo_backing_file while holding lo_lock, but LOOP_CHANGE_FD replaced lo_backing_file without that lock. The old file can then be fput() after the swap, and that fput may be the last reference. This leaves a sysfs reader that observed the old pointer able to run file_path() on a file whose final put is underway. Validation reproduced this kernel report: BUG: KCSAN: data-race in lo_ioctl / loop_attr_do_show_backing_file The buggy scenario involves two paths, with each column showing the order within that path: sysfs backing_file show: LOOP_CHANGE_FD: 1. Take lo_lock. 1. Save old_file from lo_backing_file. 2. Read lo_backing_file. 2. Store the replacement file pointer. 3. Pass it to file_path(). 3. Drop the loop-owned old_file ref. Serialize loop_assign_backing_file()'s pointer store with lo_lock, the same lock used by the sysfs show path and by __loop_clr_fd(). This keeps a sysfs reader that entered before the swap ordered before the old file can be detached and fput(), and makes readers entering after the swap see the new file. Validation reproduced this kernel report: [ 56.673265] BUG: KCSAN: data-race in lo_ioctl / loop_attr_do_show_backing_file [ 56.674430] write to 0xffff888101d21060 of 8 bytes by task 498 on cpu 1: [ 56.675365] lo_ioctl+0x99d/0xca0 [ 56.675819] blkdev_ioctl+0x2bc/0x380 [ 56.676331] __x64_sys_ioctl+0xc7/0x110 [ 56.676846] x64_sys_call+0x1092/0x1fb0 [ 56.677372] do_syscall_64+0x100/0x570 [ 56.677878] entry_SYSCALL_64_after_hwframe+0x77/0x7f [ 56.678777] read to 0xffff888101d21060 of 8 bytes by task 489 on cpu 2: [ 56.679617] loop_attr_do_show_backing_file+0x51/0xe0 [ 56.680280] dev_attr_show+0x3b/0x90 [ 56.680769] sysfs_kf_seq_show+0x139/0x1e0 [ 56.681321] kernfs_seq_show+0x9c/0xb0 [ 56.681823] seq_read_iter+0x2b3/0x830 [ 56.682336] kernfs_fop_read_iter+0x26b/0x2d0 [ 56.682917] vfs_read+0x414/0x5c0 [ 56.683393] ksys_read+0xa3/0x130 [ 56.683844] __x64_sys_read+0x41/0x50 [ 56.684344] x64_sys_call+0x1efb/0x1fb0 [ 56.684856] do_syscall_64+0x100/0x570 [ 56.685364] entry_SYSCALL_64_after_hwframe+0x77/0x7f [ 56.686252] value changed: 0xffff888104d62900 -> 0xffff888104d53680 [ 56.687275] Reported by Kernel Concurrency Sanitizer on: [ 56.687963] CPU: 2 UID: 0 PID: 489 Comm: loop_changefd_r Not tainted 7.1.0-02794-g5c7804e3279c #1 PREEMPT(lazy) [ 56.689251] Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 [ 56.690673] ================================================================== [ 62.334003] ================================================================== [ 62.334986] BUG: KCSAN: data-race in lo_ioctl / loop_attr_do_show_backing_file [ 62.336145] write to 0xffff888101d21060 of 8 bytes by task 498 on cpu 3: [ 62.337000] lo_ioctl+0x99d/0xca0 [ 62.337452] blkdev_ioctl+0x2bc/0x380 [ 62.337955] __x64_sys_ioctl+0xc7/0x110 [ 62.338468] x64_sys_call+0x1092/0x1fb0 [ 62.338993] do_syscall_64+0x100/0x570 [ 62.339493] entry_SYSCALL_64_after_hwframe+0x77/0x7f [ 62.340381] read to 0xffff888101d21060 of 8 bytes by task 495 on cpu 0: [ 62.341235] loop_attr_do_show_backing_file+0x51/0xe0 [ 62.341900] dev_attr_show+0x3b/0x90 [ 62.342385] sysfs_kf_seq_show+0x139/0x1e0 [ 62.342943] kernfs_seq_show+0x9c/0xb0 [ 62.343447] seq_read_iter+0x2b3/0x830 [ 62.343955] kernfs_fop_read_iter+0x26b/0x2d0 [ 62.344537] vfs_read+0x414/0x5c0 [ 62.344988] ksys_read+0xa3/0x130 [ 62.345438] __x64_sys_read+0x41/0x50 [ 62.345937] x64_sys_call+0x1efb/0x1fb0 [ 62.346446] do_syscall_64+0x100/0x570 [ 62.346956] entry_SYSCALL_64_after_hwframe+0x77/0x7f [ 62.347832] value changed: 0xffff888104d50f00 -> 0xffff888104cf4f00 [ 62.348871] Reported by Kernel Concurrency Sanitizer on: [ 62.349548] CPU: 0 UID: 0 PID: 495 Comm: loop_changefd_r Not tainted 7.1.0-02794-g5c7804e3279c #1 PREEMPT(lazy) [ 62.350823] Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 [ 62.352260] ================================================================== [ 65.676721] ================================================================== [ 65.677703] BUG: KCSAN: data-race in lo_ioctl / loop_attr_do_show_backing_file [ 65.678870] write to 0xffff888101d21060 of 8 bytes by task 498 on cpu 0: [ 65.679712] lo_ioctl+0x99d/0xca0 [ 65.680166] blkdev_ioctl+0x2bc/0x380 [ 65.680673] __x64_sys_ioctl+0xc7/0x110 [ 65.681187] x64_sys_call+0x1092/0x1fb0 [ 65.681707] do_syscall_64+0x100/0x570 [ 65.682214] entry_SYSCALL_64_after_hwframe+0x77/0x7f [ 65.683113] read to 0xffff888101d21060 of 8 bytes by task 497 on cpu 2: [ 65.683955] loop_attr_do_show_backing_file+0x51/0xe0 [ 65.684617] dev_attr_show+0x3b/0x90 [ 65.685109] sysfs_kf_seq_show+0x139/0x1e0 [ 65.685663] kernfs_seq_show+0x9c/0xb0 [ 65.686165] seq_read_iter+0x2b3/0x830 [ 65.686679] kernfs_fop_read_iter+0x26b/0x2d0 [ 65.687265] vfs_read+0x414/0x5c0 [ 65.687720] ksys_read+0xa3/0x130 [ 65.688171] __x64_sys_read+0x41/0x50 [ 65.688665] x64_sys_call+0x1efb/0x1fb0 [ 65.689177] do_syscall_64+0x100/0x570 [ 65.689688] entry_SYSCALL_64_after_hwframe+0x77/0x7f [ 65.690582] value changed: 0xffff888100c52600 -> 0xffff888104d54180 [ 65.691615] Reported by Kernel Concurrency Sanitizer on: [ 65.692309] CPU: 2 UID: 0 PID: 497 Comm: loop_changefd_r Not tainted 7.1.0-02794-g5c7804e3279c #1 PREEMPT(lazy) [ 65.693596] Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 [ 65.695035] ================================================================== [ 68.697953] ================================================================== [ 68.698927] BUG: KCSAN: data-race in lo_ioctl / loop_attr_do_show_backing_file [ 68.700101] write to 0xffff888101d21060 of 8 bytes by task 498 on cpu 1: Fixes: 05eb0f2 ("loop: fix deadlock when sysfs and LOOP_CLR_FD race against each other") Assisted-by: Codex:gpt-5.5 Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
Author
|
Upstream branch: bade58e |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull request for series with
subject: loop: serialize backing file swaps with sysfs readers
version: 1
url: https://patchwork.kernel.org/project/linux-block/list/?series=1115735