* [PATCH 0/2] udf: Fix race between file type conversion and writeback
@ 2026-03-23 16:30 Jan Kara
2026-03-23 16:30 ` [PATCH 1/2] writeback: Export folio_prepare_writeback() Jan Kara
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Jan Kara @ 2026-03-23 16:30 UTC (permalink / raw)
To: linux-fsdevel; +Cc: linux-mm, Jan Kara
Hello,
these patches fix a race between conversion of UDF file from inline format to
the standard format and writeback resulting in possible memory corruption.
Review/Acks are welcome in particular for the export of
folio_prepare_writeback(). I'd like to push the fix to Linus soon as it's kind
of nasty issue.
Honza
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/2] writeback: Export folio_prepare_writeback()
2026-03-23 16:30 [PATCH 0/2] udf: Fix race between file type conversion and writeback Jan Kara
@ 2026-03-23 16:30 ` Jan Kara
2026-03-23 16:30 ` [PATCH 2/2] udf: Fix race between file type conversion and writeback Jan Kara
2026-03-23 22:37 ` [syzbot ci] " syzbot ci
2 siblings, 0 replies; 5+ messages in thread
From: Jan Kara @ 2026-03-23 16:30 UTC (permalink / raw)
To: linux-fsdevel; +Cc: linux-mm, Jan Kara
The sequence of operations done in folio_prepare_writeback() is needed
practically by every writeback method. UDF is unable to easily use
writeback_iter() for inodes with inline format (due to complexities with
racing conversion and fallback) so export folio_prepare_writeback() for
it instead of opencoding it in UDF. Later we can use this helper from
other filesystems as well.
Signed-off-by: Jan Kara <jack@suse.cz>
---
include/linux/writeback.h | 2 ++
mm/page-writeback.c | 4 ++--
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
index e530112c4b3a..3e5d215c8d27 100644
--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -357,6 +357,8 @@ bool wb_over_bg_thresh(struct bdi_writeback *wb);
struct folio *writeback_iter(struct address_space *mapping,
struct writeback_control *wbc, struct folio *folio, int *error);
+bool folio_prepare_writeback(struct address_space *mapping,
+ struct writeback_control *wbc, struct folio *folio);
int do_writepages(struct address_space *mapping, struct writeback_control *wbc);
void writeback_set_ratelimit(void);
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 601a5e048d12..ceb78798fc00 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -2358,7 +2358,7 @@ void tag_pages_for_writeback(struct address_space *mapping,
}
EXPORT_SYMBOL(tag_pages_for_writeback);
-static bool folio_prepare_writeback(struct address_space *mapping,
+bool folio_prepare_writeback(struct address_space *mapping,
struct writeback_control *wbc, struct folio *folio)
{
/*
@@ -2389,7 +2389,7 @@ static bool folio_prepare_writeback(struct address_space *mapping,
return true;
}
-
+EXPORT_SYMBOL_GPL(folio_prepare_writeback);
static pgoff_t wbc_end(struct writeback_control *wbc)
{
--
2.51.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/2] udf: Fix race between file type conversion and writeback
2026-03-23 16:30 [PATCH 0/2] udf: Fix race between file type conversion and writeback Jan Kara
2026-03-23 16:30 ` [PATCH 1/2] writeback: Export folio_prepare_writeback() Jan Kara
@ 2026-03-23 16:30 ` Jan Kara
2026-03-23 22:37 ` [syzbot ci] " syzbot ci
2 siblings, 0 replies; 5+ messages in thread
From: Jan Kara @ 2026-03-23 16:30 UTC (permalink / raw)
To: linux-fsdevel; +Cc: linux-mm, Jan Kara, Jianzhou Zhao
udf_setsize() can race with udf_writepages() as follows:
udf_setsize() udf_writepages()
if (iinfo->i_alloc_type ==
ICBTAG_FLAG_AD_IN_ICB)
err = udf_expand_file_adinicb(inode);
err = udf_extend_file(inode, newsize);
udf_adinicb_writepages()
memcpy_from_file_folio() - crash
because inode size is too big.
Fix the problem by rechecking file type under folio lock in
udf_writepages() which properly serializes with
udf_expand_file_adinicb(). Since it is quite difficult to implement this
locking with current writeback_iter() logic, let's just opencode the
logic necessary to prepare (the only) folio the inode can have for
writeback.
Reported-by: Jianzhou Zhao <luckd0g@163.com>
Link: https://lore.kernel.org/all/f622c01.67ac.19cdbdd777d.Coremail.luckd0g@163.com
Signed-off-by: Jan Kara <jack@suse.cz>
---
fs/udf/inode.c | 44 ++++++++++++++++++++++++--------------------
1 file changed, 24 insertions(+), 20 deletions(-)
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 7fae8002344a..8ca73893ce2c 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -181,34 +181,38 @@ static void udf_write_failed(struct address_space *mapping, loff_t to)
}
}
-static int udf_adinicb_writepages(struct address_space *mapping,
- struct writeback_control *wbc)
+static int udf_writepages(struct address_space *mapping,
+ struct writeback_control *wbc)
{
struct inode *inode = mapping->host;
struct udf_inode_info *iinfo = UDF_I(inode);
- struct folio *folio = NULL;
- int error = 0;
- while ((folio = writeback_iter(mapping, wbc, folio, &error))) {
- BUG_ON(!folio_test_locked(folio));
- BUG_ON(folio->index != 0);
+ if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
+ struct folio *folio;
+
+ folio = filemap_lock_folio(mapping, 0);
+ if (!folio)
+ return 0;
+ /*
+ * Recheck inode type under folio lock when we are protected
+ * against udf_expand_file_adinicb(). Bail to standard writeback
+ * path if file got expanded.
+ */
+ if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
+ folio_unlock(folio);
+ goto mpage_writeback;
+ }
+ if (folio_prepare_writeback(mapping, wbc, folio)) {
+ folio_unlock(folio);
+ return 0;
+ }
memcpy_from_file_folio(iinfo->i_data + iinfo->i_lenEAttr, folio,
0, i_size_read(inode));
folio_unlock(folio);
+ mark_inode_dirty(inode);
+ return 0;
}
-
- mark_inode_dirty(inode);
- return 0;
-}
-
-static int udf_writepages(struct address_space *mapping,
- struct writeback_control *wbc)
-{
- struct inode *inode = mapping->host;
- struct udf_inode_info *iinfo = UDF_I(inode);
-
- if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
- return udf_adinicb_writepages(mapping, wbc);
+mpage_writeback:
return mpage_writepages(mapping, wbc, udf_get_block_wb);
}
--
2.51.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [syzbot ci] Re: udf: Fix race between file type conversion and writeback
2026-03-23 16:30 [PATCH 0/2] udf: Fix race between file type conversion and writeback Jan Kara
2026-03-23 16:30 ` [PATCH 1/2] writeback: Export folio_prepare_writeback() Jan Kara
2026-03-23 16:30 ` [PATCH 2/2] udf: Fix race between file type conversion and writeback Jan Kara
@ 2026-03-23 22:37 ` syzbot ci
2026-03-24 8:18 ` Jan Kara
2 siblings, 1 reply; 5+ messages in thread
From: syzbot ci @ 2026-03-23 22:37 UTC (permalink / raw)
To: jack, linux-fsdevel, linux-mm, luckd0g; +Cc: syzbot, syzkaller-bugs
syzbot ci has tested the following series
[v1] udf: Fix race between file type conversion and writeback
https://lore.kernel.org/all/20260323162617.2421-1-jack@suse.cz
* [PATCH 1/2] writeback: Export folio_prepare_writeback()
* [PATCH 2/2] udf: Fix race between file type conversion and writeback
and found the following issue:
general protection fault in folio_prepare_writeback
Full report is available here:
https://ci.syzbot.org/series/03e405d8-f247-471a-8469-f544c8393300
***
general protection fault in folio_prepare_writeback
tree: mm-new
URL: https://kernel.googlesource.com/pub/scm/linux/kernel/git/akpm/mm.git
base: af5802cff33fe3c557dff87cd3897d14241a7c6d
arch: amd64
compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
config: https://ci.syzbot.org/builds/d1944db2-4f63-4e26-b642-d71f55382c9d/config
C repro: https://ci.syzbot.org/findings/87b82667-f800-480e-b52a-38decce9e6c4/c_repro
syz repro: https://ci.syzbot.org/findings/87b82667-f800-480e-b52a-38decce9e6c4/syz_repro
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000002: 0000 [#1] SMP KASAN PTI
KASAN: null-ptr-deref in range [0x0000000000000010-0x0000000000000017]
CPU: 0 UID: 0 PID: 1860 Comm: kworker/u9:3 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
Workqueue: writeback wb_workfn (flush-7:0)
RIP: 0010:folio_prepare_writeback+0x32/0x280 mm/page-writeback.c:2371
Code: 56 41 55 41 54 53 50 48 89 d3 48 89 f5 49 89 fe 49 bd 00 00 00 00 00 fc ff df e8 f9 22 c2 ff 4c 8d 63 18 4c 89 e0 48 c1 e8 03 <42> 80 3c 28 00 74 08 4c 89 e7 e8 ef 6a 2c 00 4d 39 34 24 0f 85 bf
RSP: 0018:ffffc9000901f1e8 EFLAGS: 00010203
RAX: 0000000000000002 RBX: fffffffffffffffe RCX: ffff88810981ba80
RDX: 0000000000000000 RSI: ffffc9000901f4e0 RDI: ffff8881a659bc48
RBP: ffffc9000901f4e0 R08: ffff88810981ba80 R09: 0000000000000003
R10: 0000000000000406 R11: 0000000000000000 R12: 0000000000000016
R13: dffffc0000000000 R14: ffff8881a659bc48 R15: ffffc9000901f4e0
FS: 0000000000000000(0000) GS:ffff88818de5e000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00001b4fda9cd4b8 CR3: 0000000110906000 CR4: 00000000000006f0
Call Trace:
<TASK>
udf_writepages+0xce/0x3b0 fs/udf/inode.c:205
do_writepages+0x32e/0x550 mm/page-writeback.c:2554
__writeback_single_inode+0x133/0x11a0 fs/fs-writeback.c:1750
writeback_sb_inodes+0x992/0x1a20 fs/fs-writeback.c:2042
wb_writeback+0x456/0xb70 fs/fs-writeback.c:2227
wb_do_writeback fs/fs-writeback.c:2374 [inline]
wb_workfn+0x414/0xf50 fs/fs-writeback.c:2414
process_one_work kernel/workqueue.c:3276 [inline]
process_scheduled_works+0xb6e/0x18c0 kernel/workqueue.c:3359
worker_thread+0xa53/0xfc0 kernel/workqueue.c:3440
kthread+0x388/0x470 kernel/kthread.c:436
ret_from_fork+0x51e/0xb90 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
</TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:folio_prepare_writeback+0x32/0x280 mm/page-writeback.c:2371
Code: 56 41 55 41 54 53 50 48 89 d3 48 89 f5 49 89 fe 49 bd 00 00 00 00 00 fc ff df e8 f9 22 c2 ff 4c 8d 63 18 4c 89 e0 48 c1 e8 03 <42> 80 3c 28 00 74 08 4c 89 e7 e8 ef 6a 2c 00 4d 39 34 24 0f 85 bf
RSP: 0018:ffffc9000901f1e8 EFLAGS: 00010203
RAX: 0000000000000002 RBX: fffffffffffffffe RCX: ffff88810981ba80
RDX: 0000000000000000 RSI: ffffc9000901f4e0 RDI: ffff8881a659bc48
RBP: ffffc9000901f4e0 R08: ffff88810981ba80 R09: 0000000000000003
R10: 0000000000000406 R11: 0000000000000000 R12: 0000000000000016
R13: dffffc0000000000 R14: ffff8881a659bc48 R15: ffffc9000901f4e0
FS: 0000000000000000(0000) GS:ffff8882a945e000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00001b4fda9c7570 CR3: 0000000173314000 CR4: 00000000000006f0
----------------
Code disassembly (best guess):
0: 56 push %rsi
1: 41 55 push %r13
3: 41 54 push %r12
5: 53 push %rbx
6: 50 push %rax
7: 48 89 d3 mov %rdx,%rbx
a: 48 89 f5 mov %rsi,%rbp
d: 49 89 fe mov %rdi,%r14
10: 49 bd 00 00 00 00 00 movabs $0xdffffc0000000000,%r13
17: fc ff df
1a: e8 f9 22 c2 ff call 0xffc22318
1f: 4c 8d 63 18 lea 0x18(%rbx),%r12
23: 4c 89 e0 mov %r12,%rax
26: 48 c1 e8 03 shr $0x3,%rax
* 2a: 42 80 3c 28 00 cmpb $0x0,(%rax,%r13,1) <-- trapping instruction
2f: 74 08 je 0x39
31: 4c 89 e7 mov %r12,%rdi
34: e8 ef 6a 2c 00 call 0x2c6b28
39: 4d 39 34 24 cmp %r14,(%r12)
3d: 0f .byte 0xf
3e: 85 .byte 0x85
3f: bf .byte 0xbf
***
If these findings have caused you to resend the series or submit a
separate fix, please add the following tag to your commit message:
Tested-by: syzbot@syzkaller.appspotmail.com
---
This report is generated by a bot. It may contain errors.
syzbot ci engineers can be reached at syzkaller@googlegroups.com.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [syzbot ci] Re: udf: Fix race between file type conversion and writeback
2026-03-23 22:37 ` [syzbot ci] " syzbot ci
@ 2026-03-24 8:18 ` Jan Kara
0 siblings, 0 replies; 5+ messages in thread
From: Jan Kara @ 2026-03-24 8:18 UTC (permalink / raw)
To: syzbot ci; +Cc: jack, linux-fsdevel, linux-mm, luckd0g, syzbot, syzkaller-bugs
On Mon 23-03-26 15:37:15, syzbot ci wrote:
> syzbot ci has tested the following series
>
> [v1] udf: Fix race between file type conversion and writeback
> https://lore.kernel.org/all/20260323162617.2421-1-jack@suse.cz
> * [PATCH 1/2] writeback: Export folio_prepare_writeback()
> * [PATCH 2/2] udf: Fix race between file type conversion and writeback
>
> and found the following issue:
> general protection fault in folio_prepare_writeback
>
> Full report is available here:
> https://ci.syzbot.org/series/03e405d8-f247-471a-8469-f544c8393300
Bah, stupid me. The result of filemap_lock_folio() must be checked with
IS_ERR(), not against NULL. Will send v2.
Honza
>
> ***
>
> general protection fault in folio_prepare_writeback
>
> tree: mm-new
> URL: https://kernel.googlesource.com/pub/scm/linux/kernel/git/akpm/mm.git
> base: af5802cff33fe3c557dff87cd3897d14241a7c6d
> arch: amd64
> compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
> config: https://ci.syzbot.org/builds/d1944db2-4f63-4e26-b642-d71f55382c9d/config
> C repro: https://ci.syzbot.org/findings/87b82667-f800-480e-b52a-38decce9e6c4/c_repro
> syz repro: https://ci.syzbot.org/findings/87b82667-f800-480e-b52a-38decce9e6c4/syz_repro
>
> Oops: general protection fault, probably for non-canonical address 0xdffffc0000000002: 0000 [#1] SMP KASAN PTI
> KASAN: null-ptr-deref in range [0x0000000000000010-0x0000000000000017]
> CPU: 0 UID: 0 PID: 1860 Comm: kworker/u9:3 Not tainted syzkaller #0 PREEMPT(full)
> Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
> Workqueue: writeback wb_workfn (flush-7:0)
> RIP: 0010:folio_prepare_writeback+0x32/0x280 mm/page-writeback.c:2371
> Code: 56 41 55 41 54 53 50 48 89 d3 48 89 f5 49 89 fe 49 bd 00 00 00 00 00 fc ff df e8 f9 22 c2 ff 4c 8d 63 18 4c 89 e0 48 c1 e8 03 <42> 80 3c 28 00 74 08 4c 89 e7 e8 ef 6a 2c 00 4d 39 34 24 0f 85 bf
> RSP: 0018:ffffc9000901f1e8 EFLAGS: 00010203
> RAX: 0000000000000002 RBX: fffffffffffffffe RCX: ffff88810981ba80
> RDX: 0000000000000000 RSI: ffffc9000901f4e0 RDI: ffff8881a659bc48
> RBP: ffffc9000901f4e0 R08: ffff88810981ba80 R09: 0000000000000003
> R10: 0000000000000406 R11: 0000000000000000 R12: 0000000000000016
> R13: dffffc0000000000 R14: ffff8881a659bc48 R15: ffffc9000901f4e0
> FS: 0000000000000000(0000) GS:ffff88818de5e000(0000) knlGS:0000000000000000
> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 00001b4fda9cd4b8 CR3: 0000000110906000 CR4: 00000000000006f0
> Call Trace:
> <TASK>
> udf_writepages+0xce/0x3b0 fs/udf/inode.c:205
> do_writepages+0x32e/0x550 mm/page-writeback.c:2554
> __writeback_single_inode+0x133/0x11a0 fs/fs-writeback.c:1750
> writeback_sb_inodes+0x992/0x1a20 fs/fs-writeback.c:2042
> wb_writeback+0x456/0xb70 fs/fs-writeback.c:2227
> wb_do_writeback fs/fs-writeback.c:2374 [inline]
> wb_workfn+0x414/0xf50 fs/fs-writeback.c:2414
> process_one_work kernel/workqueue.c:3276 [inline]
> process_scheduled_works+0xb6e/0x18c0 kernel/workqueue.c:3359
> worker_thread+0xa53/0xfc0 kernel/workqueue.c:3440
> kthread+0x388/0x470 kernel/kthread.c:436
> ret_from_fork+0x51e/0xb90 arch/x86/kernel/process.c:158
> ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
> </TASK>
> Modules linked in:
> ---[ end trace 0000000000000000 ]---
> RIP: 0010:folio_prepare_writeback+0x32/0x280 mm/page-writeback.c:2371
> Code: 56 41 55 41 54 53 50 48 89 d3 48 89 f5 49 89 fe 49 bd 00 00 00 00 00 fc ff df e8 f9 22 c2 ff 4c 8d 63 18 4c 89 e0 48 c1 e8 03 <42> 80 3c 28 00 74 08 4c 89 e7 e8 ef 6a 2c 00 4d 39 34 24 0f 85 bf
> RSP: 0018:ffffc9000901f1e8 EFLAGS: 00010203
> RAX: 0000000000000002 RBX: fffffffffffffffe RCX: ffff88810981ba80
> RDX: 0000000000000000 RSI: ffffc9000901f4e0 RDI: ffff8881a659bc48
> RBP: ffffc9000901f4e0 R08: ffff88810981ba80 R09: 0000000000000003
> R10: 0000000000000406 R11: 0000000000000000 R12: 0000000000000016
> R13: dffffc0000000000 R14: ffff8881a659bc48 R15: ffffc9000901f4e0
> FS: 0000000000000000(0000) GS:ffff8882a945e000(0000) knlGS:0000000000000000
> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 00001b4fda9c7570 CR3: 0000000173314000 CR4: 00000000000006f0
> ----------------
> Code disassembly (best guess):
> 0: 56 push %rsi
> 1: 41 55 push %r13
> 3: 41 54 push %r12
> 5: 53 push %rbx
> 6: 50 push %rax
> 7: 48 89 d3 mov %rdx,%rbx
> a: 48 89 f5 mov %rsi,%rbp
> d: 49 89 fe mov %rdi,%r14
> 10: 49 bd 00 00 00 00 00 movabs $0xdffffc0000000000,%r13
> 17: fc ff df
> 1a: e8 f9 22 c2 ff call 0xffc22318
> 1f: 4c 8d 63 18 lea 0x18(%rbx),%r12
> 23: 4c 89 e0 mov %r12,%rax
> 26: 48 c1 e8 03 shr $0x3,%rax
> * 2a: 42 80 3c 28 00 cmpb $0x0,(%rax,%r13,1) <-- trapping instruction
> 2f: 74 08 je 0x39
> 31: 4c 89 e7 mov %r12,%rdi
> 34: e8 ef 6a 2c 00 call 0x2c6b28
> 39: 4d 39 34 24 cmp %r14,(%r12)
> 3d: 0f .byte 0xf
> 3e: 85 .byte 0x85
> 3f: bf .byte 0xbf
>
>
> ***
>
> If these findings have caused you to resend the series or submit a
> separate fix, please add the following tag to your commit message:
> Tested-by: syzbot@syzkaller.appspotmail.com
>
> ---
> This report is generated by a bot. It may contain errors.
> syzbot ci engineers can be reached at syzkaller@googlegroups.com.
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-03-24 8:19 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-23 16:30 [PATCH 0/2] udf: Fix race between file type conversion and writeback Jan Kara
2026-03-23 16:30 ` [PATCH 1/2] writeback: Export folio_prepare_writeback() Jan Kara
2026-03-23 16:30 ` [PATCH 2/2] udf: Fix race between file type conversion and writeback Jan Kara
2026-03-23 22:37 ` [syzbot ci] " syzbot ci
2026-03-24 8:18 ` Jan Kara
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox