public inbox for linux-mm@kvack.org
 help / color / mirror / Atom feed
* [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