public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [syzbot] [ocfs2?] [ext4?] general protection fault in jbd2_journal_dirty_metadata (2)
@ 2026-05-04 22:27 syzbot
  2026-05-04 23:52 ` Forwarded: [PATCH] jbd2: check for aborted handle in jbd2_journal_dirty_metadata() syzbot
  0 siblings, 1 reply; 2+ messages in thread
From: syzbot @ 2026-05-04 22:27 UTC (permalink / raw)
  To: jack, jlbec, joseph.qi, linux-ext4, linux-kernel, mark,
	ocfs2-devel, syzkaller-bugs, tytso

Hello,

syzbot found the following issue on:

HEAD commit:    08d0d3466664 Merge tag 'net-7.1-rc2' of git://git.kernel.o..
git tree:       upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=152f81ce580000
kernel config:  https://syzkaller.appspot.com/x/.config?x=4caf64b1ee83dac0
dashboard link: https://syzkaller.appspot.com/bug?extid=98f651460e558a21baae
compiler:       Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
syz repro:      https://syzkaller.appspot.com/x/repro.syz?x=1415f2d2580000
C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=132f81ce580000

Downloadable assets:
disk image: https://storage.googleapis.com/syzbot-assets/c5abd4fcc5ba/disk-08d0d346.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/896c46fd9ce9/vmlinux-08d0d346.xz
kernel image: https://storage.googleapis.com/syzbot-assets/04a44a684bb3/bzImage-08d0d346.xz
mounted in repro: https://storage.googleapis.com/syzbot-assets/b6c8c7ca94d0/mount_0.gz
  fsck result: OK (log: https://syzkaller.appspot.com/x/fsck.log?x=14e8a082580000)

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+98f651460e558a21baae@syzkaller.appspotmail.com

(syz.2.23,6028,0):__ocfs2_remove_xattr_range:786 ERROR: status = -30
(syz.2.23,6028,0):ocfs2_xattr_shrink_size:840 ERROR: status = -30
(syz.2.23,6028,0):__ocfs2_journal_access:724 ERROR: Error -30 getting 1 access to buffer!
(syz.2.23,6028,0):ocfs2_xa_prepare_entry:2182 ERROR: status = -30
(syz.2.23,6028,0):ocfs2_xa_set:2285 ERROR: status = -30
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] SMP KASAN NOPTI
KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
CPU: 0 UID: 0 PID: 6028 Comm: syz.2.23 Not tainted syzkaller #0 PREEMPT(full) 
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 04/18/2026
RIP: 0010:jbd2_journal_dirty_metadata+0x4a/0xd30 fs/jbd2/transaction.c:1520
Code: 00 fc ff df e8 07 27 29 ff 4c 89 fd 48 c1 ed 03 42 80 7c 35 00 00 74 08 4c 89 ff e8 f0 61 94 ff 49 8b 1f 48 89 d8 48 c1 e8 03 <42> 80 3c 30 00 74 08 48 89 df e8 d7 61 94 ff 48 89 1c 24 4c 8b 2b
RSP: 0018:ffffc90003766bc0 EFLAGS: 00010256
RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffff888035c3dc40
RDX: 0000000000000000 RSI: ffff88805927b9f8 RDI: ffff888034ddbf20
RBP: 1ffff110069bb7e4 R08: ffffffff9030a1f7 R09: 1ffffffff206143e
R10: dffffc0000000000 R11: fffffbfff206143f R12: dffffc0000000000
R13: 1ffff920006ecd94 R14: dffffc0000000000 R15: ffff888034ddbf20
FS:  000055556c64d500(0000) GS:ffff888125290000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f8ff9c72700 CR3: 000000007908f000 CR4: 0000000000350ef0
Call Trace:
 <TASK>
 ocfs2_journal_dirty+0x130/0x700 fs/ocfs2/journal.c:831
 ocfs2_xa_journal_dirty fs/ocfs2/xattr.c:1483 [inline]
 ocfs2_xa_set+0x15e3/0x2ec0 fs/ocfs2/xattr.c:2294
 ocfs2_xattr_block_set+0x3e0/0x33c0 fs/ocfs2/xattr.c:3016
 __ocfs2_xattr_set_handle+0x6b3/0xf50 fs/ocfs2/xattr.c:3418
 ocfs2_xattr_set+0xf3f/0x13e0 fs/ocfs2/xattr.c:3681
 __vfs_setxattr+0x43c/0x480 fs/xattr.c:218
 __vfs_setxattr_noperm+0x12d/0x660 fs/xattr.c:252
 vfs_setxattr+0x163/0x360 fs/xattr.c:339
 do_setxattr fs/xattr.c:654 [inline]
 filename_setxattr+0x296/0x630 fs/xattr.c:682
 path_setxattrat+0x3eb/0x440 fs/xattr.c:726
 __do_sys_setxattr fs/xattr.c:760 [inline]
 __se_sys_setxattr fs/xattr.c:756 [inline]
 __x64_sys_setxattr+0xbc/0xe0 fs/xattr.c:756
 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
 do_syscall_64+0x15f/0xf80 arch/x86/entry/syscall_64.c:94
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f8ff9d9cdd9
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 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 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007ffd9c92e118 EFLAGS: 00000246 ORIG_RAX: 00000000000000bc
RAX: ffffffffffffffda RBX: 00007f8ffa015fa0 RCX: 00007f8ff9d9cdd9
RDX: 0000000000000000 RSI: 0000200000000140 RDI: 0000200000000080
RBP: 00007f8ff9e32d69 R08: 0000000000000002 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007f8ffa015fac R14: 00007f8ffa015fa0 R15: 00007f8ffa015fa0
 </TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:jbd2_journal_dirty_metadata+0x4a/0xd30 fs/jbd2/transaction.c:1520
Code: 00 fc ff df e8 07 27 29 ff 4c 89 fd 48 c1 ed 03 42 80 7c 35 00 00 74 08 4c 89 ff e8 f0 61 94 ff 49 8b 1f 48 89 d8 48 c1 e8 03 <42> 80 3c 30 00 74 08 48 89 df e8 d7 61 94 ff 48 89 1c 24 4c 8b 2b
RSP: 0018:ffffc90003766bc0 EFLAGS: 00010256
RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffff888035c3dc40
RDX: 0000000000000000 RSI: ffff88805927b9f8 RDI: ffff888034ddbf20
RBP: 1ffff110069bb7e4 R08: ffffffff9030a1f7 R09: 1ffffffff206143e
R10: dffffc0000000000 R11: fffffbfff206143f R12: dffffc0000000000
R13: 1ffff920006ecd94 R14: dffffc0000000000 R15: ffff888034ddbf20
FS:  000055556c64d500(0000) GS:ffff888125290000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000557909eb6950 CR3: 000000007908f000 CR4: 0000000000350ef0
----------------
Code disassembly (best guess), 4 bytes skipped:
   0:	e8 07 27 29 ff       	call   0xff29270c
   5:	4c 89 fd             	mov    %r15,%rbp
   8:	48 c1 ed 03          	shr    $0x3,%rbp
   c:	42 80 7c 35 00 00    	cmpb   $0x0,0x0(%rbp,%r14,1)
  12:	74 08                	je     0x1c
  14:	4c 89 ff             	mov    %r15,%rdi
  17:	e8 f0 61 94 ff       	call   0xff94620c
  1c:	49 8b 1f             	mov    (%r15),%rbx
  1f:	48 89 d8             	mov    %rbx,%rax
  22:	48 c1 e8 03          	shr    $0x3,%rax
* 26:	42 80 3c 30 00       	cmpb   $0x0,(%rax,%r14,1) <-- trapping instruction
  2b:	74 08                	je     0x35
  2d:	48 89 df             	mov    %rbx,%rdi
  30:	e8 d7 61 94 ff       	call   0xff94620c
  35:	48 89 1c 24          	mov    %rbx,(%rsp)
  39:	4c 8b 2b             	mov    (%rbx),%r13


---
This report is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.

syzbot will keep track of this issue. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.

If the report is already addressed, let syzbot know by replying with:
#syz fix: exact-commit-title

If you want syzbot to run the reproducer, reply with:
#syz test: git://repo/address.git branch-or-commit-hash
If you attach or paste a git patch, syzbot will apply it before testing.

If you want to overwrite report's subsystems, reply with:
#syz set subsystems: new-subsystem
(See the list of subsystem names on the web dashboard)

If the report is a duplicate of another one, reply with:
#syz dup: exact-subject-of-another-report

If you want to undo deduplication, reply with:
#syz undup

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Forwarded: [PATCH] jbd2: check for aborted handle in jbd2_journal_dirty_metadata()
  2026-05-04 22:27 [syzbot] [ocfs2?] [ext4?] general protection fault in jbd2_journal_dirty_metadata (2) syzbot
@ 2026-05-04 23:52 ` syzbot
  0 siblings, 0 replies; 2+ messages in thread
From: syzbot @ 2026-05-04 23:52 UTC (permalink / raw)
  To: linux-kernel, syzkaller-bugs

For archival purposes, forwarding an incoming command email to
linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com.

***

Subject: [PATCH] jbd2: check for aborted handle in jbd2_journal_dirty_metadata()
Author: kartikey406@gmail.com

#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master


jbd2_journal_dirty_metadata() unconditionally dereferences
handle->h_transaction at function entry to obtain the journal pointer:

	transaction_t *transaction = handle->h_transaction;
	journal_t *journal = transaction->t_journal;

However, h_transaction may legitimately be NULL for an aborted handle.
The is_handle_aborted() helper in include/linux/jbd2.h explicitly
treats !h_transaction as one of the aborted states:

	if (handle->h_aborted || !handle->h_transaction)
		return 1;

Every other entry point in fs/jbd2/transaction.c
(jbd2_journal_get_{write,undo,create}_access, jbd2_journal_extend,
jbd2_journal_restart, jbd2_journal_stop, etc.) guards against this
with an is_handle_aborted() check before any dereference of
h_transaction. jbd2_journal_dirty_metadata() was missing this guard.

This is reachable from ocfs2's xattr code. ocfs2_xa_set() intentionally
falls through to ocfs2_xa_journal_dirty() even after
ocfs2_xa_prepare_entry() fails, on the assumption that the buffer
needs to be journaled to record any partial modifications (see the
comment above the out_dirty label in fs/ocfs2/xattr.c). If the failure
was caused by the journal being aborted -- e.g. an underlying I/O
error during a sub-operation such as __ocfs2_remove_xattr_range() --
the handle's h_transaction has been cleared by the abort path, and
the unconditional deref in jbd2_journal_dirty_metadata() becomes a
NULL deref.

Reproduced by syzbot with a crafted ocfs2 image where I/O against the
loop device backing the mount is sabotaged via LOOP_SET_STATUS64
between two setxattr() calls, causing the second setxattr (which
truncates an external xattr value) to abort the journal mid-flight:

  Oops: general protection fault, probably for non-canonical
        address 0xdffffc0000000000
  KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
  RIP: jbd2_journal_dirty_metadata+0x4a/0xd30 fs/jbd2/transaction.c:1520
  Call Trace:
   ocfs2_journal_dirty+0x130/0x700 fs/ocfs2/journal.c:831
   ocfs2_xa_journal_dirty fs/ocfs2/xattr.c:1483 [inline]
   ocfs2_xa_set+0x15e3/0x2ec0 fs/ocfs2/xattr.c:2294
   ocfs2_xattr_block_set+0x3e0/0x33c0 fs/ocfs2/xattr.c:3016
   __ocfs2_xattr_set_handle+0x6b3/0xf50 fs/ocfs2/xattr.c:3418
   ocfs2_xattr_set+0xf3f/0x13e0 fs/ocfs2/xattr.c:3681
   __vfs_setxattr+0x43c/0x480 fs/xattr.c:218
   ...

Fix by adding the standard is_handle_aborted() guard at the top of
jbd2_journal_dirty_metadata() and returning -EROFS, matching the
pattern used by every other entry point in this file.
ocfs2_journal_dirty() already handles a non-zero return from
jbd2_journal_dirty_metadata() correctly.

Reported-by: syzbot+98f651460e558a21baae@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=98f651460e558a21baae
Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
---
 fs/jbd2/transaction.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index 4885903bbd10..aa0be9e9c876 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -1516,14 +1516,19 @@ void jbd2_buffer_abort_trigger(struct journal_head *jh,
  */
 int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
 {
-	transaction_t *transaction = handle->h_transaction;
-	journal_t *journal = transaction->t_journal;
+	transaction_t *transaction;
+	journal_t *journal;
 	struct journal_head *jh;
 	int ret = 0;
 
+	if (is_handle_aborted(handle))
+		return -EROFS;
 	if (!buffer_jbd(bh))
 		return -EUCLEAN;
 
+	transaction = handle->h_transaction;
+	journal = transaction->t_journal;
+
 	/*
 	 * We don't grab jh reference here since the buffer must be part
 	 * of the running transaction.
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-05-04 23:52 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-04 22:27 [syzbot] [ocfs2?] [ext4?] general protection fault in jbd2_journal_dirty_metadata (2) syzbot
2026-05-04 23:52 ` Forwarded: [PATCH] jbd2: check for aborted handle in jbd2_journal_dirty_metadata() syzbot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox