fs/hfsplus/super.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
syzbot reported a memory leak in the hfsplus mount path when the mount
fails, which occurs because the fs_context API moves ownership of
fc->s_fs_info to sb->s_fs_info early in sget_fc().
When filesystems are mounted using the new API, the VFS (specifically
sget_fc) transfers the ownership of the context's s_fs_info (the 'sbi'
struct) to the superblock (sb->s_fs_info) and clears the context
pointer.
If the mount fails after this transfer the VFS calls
deactivate_locked_super, which invokes the filesystem's kill_sb
callback. Previously, hfsplus used the generic kill_block_super, which
does not free sb->s_fs_info, resulting in the 'sbi' structure and its
loaded NLS tables being leaked.
Fix this by implementing a filesystem-specific ->kill_sb() that frees
sb->s_fs_info and its NLS resources before calling kill_block_super().
Also remove the early kfree(sbi) from hfsplus_fill_super()’s error path,
because the superblock unconditionally owns s_fs_info when using the
fs_context API.
Testing:
This fix was verified by building the kernel with the .config provided
by the syzkaller reporter and running the reproducer. The reproducer
now runs successfully without triggering any memory leaks or kernel errors.
#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git e69c7c175115
Reported-by: syzbot+99f6ed51479b86ac4c41@syzkaller.appspotmail.com
Signed-off-by: Swaraj Gaikwad <swarajgaikwad1925@gmail.com>
---
fs/hfsplus/super.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index 16bc4abc67e0..fa7420d08da1 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -629,7 +629,6 @@ static int hfsplus_fill_super(struct super_block *sb, struct fs_context *fc)
out_unload_nls:
unload_nls(sbi->nls);
unload_nls(nls);
- kfree(sbi);
return err;
}
@@ -688,10 +687,23 @@ static int hfsplus_init_fs_context(struct fs_context *fc)
return 0;
}
+static void hfsplus_kill_sb(struct super_block *sb)
+{
+ struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb);
+
+ if (sbi) {
+ unload_nls(sbi->nls);
+ kfree(sbi);
+ sb->s_fs_info = NULL;
+ }
+
+ kill_block_super(sb);
+}
+
static struct file_system_type hfsplus_fs_type = {
.owner = THIS_MODULE,
.name = "hfsplus",
- .kill_sb = kill_block_super,
+ .kill_sb = hfsplus_kill_sb,
.fs_flags = FS_REQUIRES_DEV,
.init_fs_context = hfsplus_init_fs_context,
};
base-commit: 6bda50f4333fa61c07f04f790fdd4e2c9f4ca610
--
2.52.0
syzbot ci has tested the following series [v1] hfsplus: fix memory leak on mount failure https://lore.kernel.org/all/20251206000902.71178-1-swarajgaikwad1925@gmail.com * [PATCH v1] hfsplus: fix memory leak on mount failure and found the following issues: * SYZFAIL: failed to recv rpc * WARNING: ODEBUG bug in hfsplus_kill_sb * general protection fault in __timer_delete * general protection fault in hfsplus_sync_fs Full report is available here: https://ci.syzbot.org/series/ea775ab1-67a5-4497-b4d6-8c7b2b7d90aa *** SYZFAIL: failed to recv rpc tree: torvalds URL: https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux base: 2061f18ad76ecaddf8ed17df81b8611ea88dbddd arch: amd64 compiler: Debian clang version 20.1.8 (++20250708063551+0c9f909b7976-1~exp1~20250708183702.136), Debian LLD 20.1.8 config: https://ci.syzbot.org/builds/591f3943-d010-4b2d-a026-67cc75802376/config C repro: https://ci.syzbot.org/findings/53a2b5e3-41ae-4650-9300-ec3fdd87f47a/c_repro syz repro: https://ci.syzbot.org/findings/53a2b5e3-41ae-4650-9300-ec3fdd87f47a/syz_repro SYZFAIL: failed to recv rpc *** WARNING: ODEBUG bug in hfsplus_kill_sb tree: torvalds URL: https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux base: 2061f18ad76ecaddf8ed17df81b8611ea88dbddd arch: amd64 compiler: Debian clang version 20.1.8 (++20250708063551+0c9f909b7976-1~exp1~20250708183702.136), Debian LLD 20.1.8 config: https://ci.syzbot.org/builds/591f3943-d010-4b2d-a026-67cc75802376/config C repro: https://ci.syzbot.org/findings/3c918e05-49e7-4855-bee1-5aafc9a5b5a4/c_repro syz repro: https://ci.syzbot.org/findings/3c918e05-49e7-4855-bee1-5aafc9a5b5a4/syz_repro ------------[ cut here ]------------ ODEBUG: free active (active state 0) object: ffff88810a17ea38 object type: timer_list hint: delayed_sync_fs+0x0/0xf0 fs/hfsplus/super.c:-1 WARNING: lib/debugobjects.c:615 at 0x0, CPU#1: syz-executor/5946 Modules linked in: CPU: 1 UID: 0 PID: 5946 Comm: syz-executor 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 RIP: 0010:debug_print_object lib/debugobjects.c:612 [inline] RIP: 0010:__debug_check_no_obj_freed lib/debugobjects.c:1099 [inline] RIP: 0010:debug_check_no_obj_freed+0x44a/0x550 lib/debugobjects.c:1129 Code: 89 44 24 20 e8 47 4a 92 fd 48 8b 44 24 20 4c 8b 4d 00 4c 89 ef 48 c7 c6 20 02 c0 8b 48 c7 c2 40 07 c0 8b 8b 0c 24 4d 89 f8 50 <67> 48 0f b9 3a 48 83 c4 08 4c 8b 6c 24 18 48 b9 00 00 00 00 00 fc RSP: 0018:ffffc900032b7c18 EFLAGS: 00010246 RAX: ffffffff829ca540 RBX: ffffffff99a849a0 RCX: 0000000000000000 RDX: ffffffff8bc00740 RSI: ffffffff8bc00220 RDI: ffffffff8f8b7a70 RBP: ffffffff8b6d2540 R08: ffff88810a17ea38 R09: ffffffff8b6d36a0 R10: dffffc0000000000 R11: ffffffff81ae6210 R12: ffff88810a17ec00 R13: ffffffff8f8b7a70 R14: ffff88810a17e000 R15: ffff88810a17ea38 FS: 0000555587657500(0000) GS:ffff8882a9e8e000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000055b55b316738 CR3: 0000000175d56000 CR4: 00000000000006f0 Call Trace: <TASK> slab_free_hook mm/slub.c:2471 [inline] slab_free mm/slub.c:6663 [inline] kfree+0x13b/0x660 mm/slub.c:6871 hfsplus_kill_sb+0x72/0xb0 fs/hfsplus/super.c:717 deactivate_locked_super+0xbc/0x130 fs/super.c:474 cleanup_mnt+0x425/0x4c0 fs/namespace.c:1318 task_work_run+0x1d4/0x260 kernel/task_work.c:233 resume_user_mode_work include/linux/resume_user_mode.h:50 [inline] __exit_to_user_mode_loop kernel/entry/common.c:44 [inline] exit_to_user_mode_loop+0xff/0x4f0 kernel/entry/common.c:75 __exit_to_user_mode_prepare include/linux/irq-entry-common.h:226 [inline] syscall_exit_to_user_mode_prepare include/linux/irq-entry-common.h:256 [inline] syscall_exit_to_user_mode_work include/linux/entry-common.h:159 [inline] syscall_exit_to_user_mode include/linux/entry-common.h:194 [inline] do_syscall_64+0x2e3/0xf80 arch/x86/entry/syscall_64.c:100 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f540cf90af7 Code: a8 ff ff ff f7 d8 64 89 01 48 83 c8 ff c3 0f 1f 44 00 00 31 f6 e9 09 00 00 00 66 0f 1f 84 00 00 00 00 00 b8 a6 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 01 c3 48 c7 c2 a8 ff ff ff f7 d8 64 89 02 b8 RSP: 002b:00007ffc80b82ab8 EFLAGS: 00000246 ORIG_RAX: 00000000000000a6 RAX: 0000000000000000 RBX: 00007f540cfee72f RCX: 00007f540cf90af7 RDX: 0000000000000000 RSI: 0000000000000009 RDI: 00007ffc80b82b70 RBP: 00007ffc80b82b70 R08: 0000000000000000 R09: 0000000000000000 R10: 00000000ffffffff R11: 0000000000000246 R12: 00007ffc80b83c00 R13: 00007f540cfee72f R14: 000000000001120e R15: 00007ffc80b83c40 </TASK> ---------------- Code disassembly (best guess): 0: 89 44 24 20 mov %eax,0x20(%rsp) 4: e8 47 4a 92 fd call 0xfd924a50 9: 48 8b 44 24 20 mov 0x20(%rsp),%rax e: 4c 8b 4d 00 mov 0x0(%rbp),%r9 12: 4c 89 ef mov %r13,%rdi 15: 48 c7 c6 20 02 c0 8b mov $0xffffffff8bc00220,%rsi 1c: 48 c7 c2 40 07 c0 8b mov $0xffffffff8bc00740,%rdx 23: 8b 0c 24 mov (%rsp),%ecx 26: 4d 89 f8 mov %r15,%r8 29: 50 push %rax * 2a: 67 48 0f b9 3a ud1 (%edx),%rdi <-- trapping instruction 2f: 48 83 c4 08 add $0x8,%rsp 33: 4c 8b 6c 24 18 mov 0x18(%rsp),%r13 38: 48 rex.W 39: b9 00 00 00 00 mov $0x0,%ecx 3e: 00 fc add %bh,%ah *** general protection fault in __timer_delete tree: torvalds URL: https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux base: 2061f18ad76ecaddf8ed17df81b8611ea88dbddd arch: amd64 compiler: Debian clang version 20.1.8 (++20250708063551+0c9f909b7976-1~exp1~20250708183702.136), Debian LLD 20.1.8 config: https://ci.syzbot.org/builds/591f3943-d010-4b2d-a026-67cc75802376/config syz repro: https://ci.syzbot.org/findings/58118c78-00cf-40ba-b5b2-a878d7311794/syz_repro Oops: general protection fault, probably for non-canonical address 0xdffffc0000000048: 0000 [#1] SMP KASAN PTI KASAN: null-ptr-deref in range [0x0000000000000240-0x0000000000000247] CPU: 1 UID: 0 PID: 5944 Comm: syz-executor 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 RIP: 0010:timer_is_static_object+0x26/0x80 kernel/time/timer.c:691 Code: 90 90 90 90 f3 0f 1e fa 41 57 41 56 53 48 89 fb 49 bf 00 00 00 00 00 fc ff df e8 95 e8 12 00 4c 8d 73 08 4c 89 f0 48 c1 e8 03 <42> 80 3c 38 00 74 08 4c 89 f7 e8 8b e0 78 00 49 83 3e 00 74 09 e8 RSP: 0018:ffffc900044279a8 EFLAGS: 00010006 RAX: 0000000000000048 RBX: 0000000000000238 RCX: ffff88817417d7c0 RDX: 0000000000000000 RSI: 0000000000000004 RDI: 0000000000000238 RBP: ffffffff99a2bcc0 R08: 0000000000000003 R09: 0000000000000004 R10: dffffc0000000000 R11: ffffffff81ae62d0 R12: ffffffff8b6d2550 R13: fffffffffffffffe R14: 0000000000000240 R15: dffffc0000000000 FS: 000055555c51f500(0000) GS:ffff8882a9e8e000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007ffd2077ec08 CR3: 00000001138de000 CR4: 00000000000006f0 Call Trace: <TASK> lookup_object_or_alloc lib/debugobjects.c:679 [inline] debug_object_assert_init+0x16f/0x380 lib/debugobjects.c:1008 debug_timer_assert_init kernel/time/timer.c:803 [inline] debug_assert_init kernel/time/timer.c:848 [inline] __timer_delete+0x31/0x390 kernel/time/timer.c:1366 try_to_grab_pending kernel/workqueue.c:2061 [inline] work_grab_pending+0x121/0x990 kernel/workqueue.c:2154 __cancel_work+0x85/0x2c0 kernel/workqueue.c:4368 __cancel_work_sync+0x1f/0x110 kernel/workqueue.c:4385 hfsplus_put_super+0x56/0x3e0 fs/hfsplus/super.c:328 generic_shutdown_super+0x135/0x2c0 fs/super.c:643 kill_block_super+0x44/0x90 fs/super.c:1730 deactivate_locked_super+0xbc/0x130 fs/super.c:474 cleanup_mnt+0x425/0x4c0 fs/namespace.c:1318 task_work_run+0x1d4/0x260 kernel/task_work.c:233 resume_user_mode_work include/linux/resume_user_mode.h:50 [inline] __exit_to_user_mode_loop kernel/entry/common.c:44 [inline] exit_to_user_mode_loop+0xff/0x4f0 kernel/entry/common.c:75 __exit_to_user_mode_prepare include/linux/irq-entry-common.h:226 [inline] syscall_exit_to_user_mode_prepare include/linux/irq-entry-common.h:256 [inline] syscall_exit_to_user_mode_work include/linux/entry-common.h:159 [inline] syscall_exit_to_user_mode include/linux/entry-common.h:194 [inline] do_syscall_64+0x2e3/0xf80 arch/x86/entry/syscall_64.c:100 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f3b71f90af7 Code: a8 ff ff ff f7 d8 64 89 01 48 83 c8 ff c3 0f 1f 44 00 00 31 f6 e9 09 00 00 00 66 0f 1f 84 00 00 00 00 00 b8 a6 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 01 c3 48 c7 c2 a8 ff ff ff f7 d8 64 89 02 b8 RSP: 002b:00007ffd2077f3b8 EFLAGS: 00000246 ORIG_RAX: 00000000000000a6 RAX: 0000000000000000 RBX: 00007f3b71fee72f RCX: 00007f3b71f90af7 RDX: 0000000000000000 RSI: 0000000000000009 RDI: 00007ffd2077f470 RBP: 00007ffd2077f470 R08: 0000000000000000 R09: 0000000000000000 R10: 00000000ffffffff R11: 0000000000000246 R12: 00007ffd20780500 R13: 00007f3b71fee72f R14: 000000000000f9eb R15: 00007ffd20780540 </TASK> Modules linked in: ---[ end trace 0000000000000000 ]--- RIP: 0010:timer_is_static_object+0x26/0x80 kernel/time/timer.c:691 Code: 90 90 90 90 f3 0f 1e fa 41 57 41 56 53 48 89 fb 49 bf 00 00 00 00 00 fc ff df e8 95 e8 12 00 4c 8d 73 08 4c 89 f0 48 c1 e8 03 <42> 80 3c 38 00 74 08 4c 89 f7 e8 8b e0 78 00 49 83 3e 00 74 09 e8 RSP: 0018:ffffc900044279a8 EFLAGS: 00010006 RAX: 0000000000000048 RBX: 0000000000000238 RCX: ffff88817417d7c0 RDX: 0000000000000000 RSI: 0000000000000004 RDI: 0000000000000238 RBP: ffffffff99a2bcc0 R08: 0000000000000003 R09: 0000000000000004 R10: dffffc0000000000 R11: ffffffff81ae62d0 R12: ffffffff8b6d2550 R13: fffffffffffffffe R14: 0000000000000240 R15: dffffc0000000000 FS: 000055555c51f500(0000) GS:ffff8882a9e8e000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007ffd2077ec08 CR3: 00000001138de000 CR4: 00000000000006f0 ---------------- Code disassembly (best guess): 0: 90 nop 1: 90 nop 2: 90 nop 3: 90 nop 4: f3 0f 1e fa endbr64 8: 41 57 push %r15 a: 41 56 push %r14 c: 53 push %rbx d: 48 89 fb mov %rdi,%rbx 10: 49 bf 00 00 00 00 00 movabs $0xdffffc0000000000,%r15 17: fc ff df 1a: e8 95 e8 12 00 call 0x12e8b4 1f: 4c 8d 73 08 lea 0x8(%rbx),%r14 23: 4c 89 f0 mov %r14,%rax 26: 48 c1 e8 03 shr $0x3,%rax * 2a: 42 80 3c 38 00 cmpb $0x0,(%rax,%r15,1) <-- trapping instruction 2f: 74 08 je 0x39 31: 4c 89 f7 mov %r14,%rdi 34: e8 8b e0 78 00 call 0x78e0c4 39: 49 83 3e 00 cmpq $0x0,(%r14) 3d: 74 09 je 0x48 3f: e8 .byte 0xe8 *** general protection fault in hfsplus_sync_fs tree: torvalds URL: https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux base: 2061f18ad76ecaddf8ed17df81b8611ea88dbddd arch: amd64 compiler: Debian clang version 20.1.8 (++20250708063551+0c9f909b7976-1~exp1~20250708183702.136), Debian LLD 20.1.8 config: https://ci.syzbot.org/builds/591f3943-d010-4b2d-a026-67cc75802376/config C repro: https://ci.syzbot.org/findings/990368ba-5843-438f-bf7c-132c134aa1f3/c_repro syz repro: https://ci.syzbot.org/findings/990368ba-5843-438f-bf7c-132c134aa1f3/syz_repro Oops: general protection fault, probably for non-canonical address 0xdffffc0000000005: 0000 [#1] SMP KASAN PTI KASAN: null-ptr-deref in range [0x0000000000000028-0x000000000000002f] CPU: 0 UID: 0 PID: 5946 Comm: syz-executor 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 RIP: 0010:hfsplus_sync_fs+0x70/0x3d0 fs/hfsplus/super.c:255 Code: 31 ff 89 ee e8 31 a9 24 ff 85 ed 0f 84 71 01 00 00 4c 89 24 24 0f 1f 44 00 00 e8 db a4 24 ff 4d 8d 7e 28 4c 89 f8 48 c1 e8 03 <80> 3c 18 00 74 08 4c 89 ff e8 d2 9c 8a ff 4d 8b 3f 49 83 c7 08 4c RSP: 0018:ffffc900036e7a48 EFLAGS: 00010206 RAX: 0000000000000005 RBX: dffffc0000000000 RCX: ffff88810bbc57c0 RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000000 RBP: 0000000000000001 R08: ffffc900036e78a7 R09: 1ffff920006dcf14 R10: dffffc0000000000 R11: ffffffff829ca640 R12: ffff88811624e000 R13: ffff88811624e158 R14: 0000000000000000 R15: 0000000000000028 FS: 0000555564915500(0000) GS:ffff88818ea8e000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000000c00003e720 CR3: 0000000011796000 CR4: 00000000000006f0 Call Trace: <TASK> sync_filesystem+0x1cf/0x230 fs/sync.c:66 generic_shutdown_super+0x6f/0x2c0 fs/super.c:622 kill_block_super+0x44/0x90 fs/super.c:1730 deactivate_locked_super+0xbc/0x130 fs/super.c:474 cleanup_mnt+0x425/0x4c0 fs/namespace.c:1318 task_work_run+0x1d4/0x260 kernel/task_work.c:233 get_signal+0x11ec/0x1340 kernel/signal.c:2807 arch_do_signal_or_restart+0x9a/0x7a0 arch/x86/kernel/signal.c:337 __exit_to_user_mode_loop kernel/entry/common.c:41 [inline] exit_to_user_mode_loop+0x87/0x4f0 kernel/entry/common.c:75 __exit_to_user_mode_prepare include/linux/irq-entry-common.h:226 [inline] syscall_exit_to_user_mode_prepare include/linux/irq-entry-common.h:256 [inline] syscall_exit_to_user_mode_work include/linux/entry-common.h:159 [inline] syscall_exit_to_user_mode include/linux/entry-common.h:194 [inline] do_syscall_64+0x2e3/0xf80 arch/x86/entry/syscall_64.c:100 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7fdd6ef90af7 Code: a8 ff ff ff f7 d8 64 89 01 48 83 c8 ff c3 0f 1f 44 00 00 31 f6 e9 09 00 00 00 66 0f 1f 84 00 00 00 00 00 b8 a6 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 01 c3 48 c7 c2 a8 ff ff ff f7 d8 64 89 02 b8 RSP: 002b:00007ffd2aacb428 EFLAGS: 00000246 ORIG_RAX: 00000000000000a6 RAX: 0000000000000000 RBX: 00007fdd6efee72f RCX: 00007fdd6ef90af7 RDX: 0000000000000000 RSI: 0000000000000009 RDI: 00007ffd2aacb4e0 RBP: 00007ffd2aacb4e0 R08: 0000000000000000 R09: 0000000000000000 R10: 00000000ffffffff R11: 0000000000000246 R12: 00007ffd2aacc570 R13: 00007fdd6efee72f R14: 000000000000febb R15: 00007ffd2aacc5b0 </TASK> Modules linked in: ---[ end trace 0000000000000000 ]--- RIP: 0010:hfsplus_sync_fs+0x70/0x3d0 fs/hfsplus/super.c:255 Code: 31 ff 89 ee e8 31 a9 24 ff 85 ed 0f 84 71 01 00 00 4c 89 24 24 0f 1f 44 00 00 e8 db a4 24 ff 4d 8d 7e 28 4c 89 f8 48 c1 e8 03 <80> 3c 18 00 74 08 4c 89 ff e8 d2 9c 8a ff 4d 8b 3f 49 83 c7 08 4c RSP: 0018:ffffc900036e7a48 EFLAGS: 00010206 RAX: 0000000000000005 RBX: dffffc0000000000 RCX: ffff88810bbc57c0 RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000000 RBP: 0000000000000001 R08: ffffc900036e78a7 R09: 1ffff920006dcf14 R10: dffffc0000000000 R11: ffffffff829ca640 R12: ffff88811624e000 R13: ffff88811624e158 R14: 0000000000000000 R15: 0000000000000028 FS: 0000555564915500(0000) GS:ffff8882a9e8e000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000055ccfe37e9e0 CR3: 0000000011796000 CR4: 00000000000006f0 ---------------- Code disassembly (best guess): 0: 31 ff xor %edi,%edi 2: 89 ee mov %ebp,%esi 4: e8 31 a9 24 ff call 0xff24a93a 9: 85 ed test %ebp,%ebp b: 0f 84 71 01 00 00 je 0x182 11: 4c 89 24 24 mov %r12,(%rsp) 15: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) 1a: e8 db a4 24 ff call 0xff24a4fa 1f: 4d 8d 7e 28 lea 0x28(%r14),%r15 23: 4c 89 f8 mov %r15,%rax 26: 48 c1 e8 03 shr $0x3,%rax * 2a: 80 3c 18 00 cmpb $0x0,(%rax,%rbx,1) <-- trapping instruction 2e: 74 08 je 0x38 30: 4c 89 ff mov %r15,%rdi 33: e8 d2 9c 8a ff call 0xff8a9d0a 38: 4d 8b 3f mov (%r15),%r15 3b: 49 83 c7 08 add $0x8,%r15 3f: 4c rex.WR *** 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.
On Sat, 2025-12-06 at 00:09 +0000, Swaraj Gaikwad wrote:
> syzbot reported a memory leak in the hfsplus mount path when the
> mount
> fails, which occurs because the fs_context API moves ownership of
> fc->s_fs_info to sb->s_fs_info early in sget_fc().
>
> When filesystems are mounted using the new API, the VFS (specifically
> sget_fc) transfers the ownership of the context's s_fs_info (the
> 'sbi'
> struct) to the superblock (sb->s_fs_info) and clears the context
> pointer.
>
> If the mount fails after this transfer the VFS calls
> deactivate_locked_super, which invokes the filesystem's kill_sb
> callback. Previously, hfsplus used the generic kill_block_super,
> which
> does not free sb->s_fs_info, resulting in the 'sbi' structure and its
> loaded NLS tables being leaked.
>
> Fix this by implementing a filesystem-specific ->kill_sb() that frees
> sb->s_fs_info and its NLS resources before calling
> kill_block_super().
> Also remove the early kfree(sbi) from hfsplus_fill_super()’s error
> path,
> because the superblock unconditionally owns s_fs_info when using the
> fs_context API.
>
> Testing:
> This fix was verified by building the kernel with the .config
> provided
> by the syzkaller reporter and running the reproducer. The reproducer
> now runs successfully without triggering any memory leaks or kernel
> errors.
>
> #syz test:
> git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
> e69c7c175115
>
> Reported-by: syzbot+99f6ed51479b86ac4c41@syzkaller.appspotmail.com
> Signed-off-by: Swaraj Gaikwad <swarajgaikwad1925@gmail.com>
> ---
> fs/hfsplus/super.c | 16 ++++++++++++++--
> 1 file changed, 14 insertions(+), 2 deletions(-)
>
> diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
> index 16bc4abc67e0..fa7420d08da1 100644
> --- a/fs/hfsplus/super.c
> +++ b/fs/hfsplus/super.c
> @@ -629,7 +629,6 @@ static int hfsplus_fill_super(struct super_block
> *sb, struct fs_context *fc)
> out_unload_nls:
> unload_nls(sbi->nls);
> unload_nls(nls);
> - kfree(sbi);
> return err;
> }
>
> @@ -688,10 +687,23 @@ static int hfsplus_init_fs_context(struct
> fs_context *fc)
> return 0;
> }
>
> +static void hfsplus_kill_sb(struct super_block *sb)
> +{
> + struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb);
> +
> + if (sbi) {
> + unload_nls(sbi->nls);
> + kfree(sbi);
> + sb->s_fs_info = NULL;
> + }
> +
> + kill_block_super(sb);
> +}
> +
> static struct file_system_type hfsplus_fs_type = {
> .owner = THIS_MODULE,
> .name = "hfsplus",
> - .kill_sb = kill_block_super,
> + .kill_sb = hfsplus_kill_sb,
> .fs_flags = FS_REQUIRES_DEV,
> .init_fs_context = hfsplus_init_fs_context,
> };
>
> base-commit: 6bda50f4333fa61c07f04f790fdd4e2c9f4ca610
> --
> 2.52.0
Sorry, but this patch [1] already fixes the issue.
Thanks,
Slava.
[1]
https://lore.kernel.org/linux-fsdevel/20251201222843.82310-3-mehdi.benhadjkhelifa@gmail.com/
Hello,
syzbot tried to test the proposed patch but the build/boot failed:
SYZFAIL: failed to recv rpc
SYZFAIL: failed to recv rpc
fd=3 want=4 recv=0 n=0 (errno 9: Bad file descriptor)
Warning: Permanently added '10.128.0.245' (ED25519) to the list of known hosts.
2025/12/05 19:05:15 parsed 1 programs
[ 55.119214][ T5818] cgroup: Unknown subsys name 'net'
[ 55.259974][ T5818] cgroup: Unknown subsys name 'cpuset'
[ 55.266582][ T5818] cgroup: Unknown subsys name 'rlimit'
Setting up swapspace version 1, size = 127995904 bytes
[ 63.696572][ T5818] Adding 124996k swap on ./swap-file. Priority:0 extents:1 across:124996k
[ 65.016628][ T5828] soft_limit_in_bytes is deprecated and will be removed. Please report your usecase to linux-mm@kvack.org if you depend on this functionality.
[ 65.422993][ T5880] Bluetooth: hci0: unexpected cc 0x0c03 length: 249 > 1
[ 65.430458][ T5880] Bluetooth: hci0: unexpected cc 0x1003 length: 249 > 9
[ 65.437558][ T5880] Bluetooth: hci0: unexpected cc 0x1001 length: 249 > 9
[ 65.445167][ T5880] Bluetooth: hci0: unexpected cc 0x0c23 length: 249 > 4
[ 65.452744][ T5880] Bluetooth: hci0: unexpected cc 0x0c38 length: 249 > 2
[ 65.561974][ T5890] chnl_net:caif_netlink_parms(): no params data found
[ 65.584453][ T5890] bridge0: port 1(bridge_slave_0) entered blocking state
[ 65.591882][ T5890] bridge0: port 1(bridge_slave_0) entered disabled state
[ 65.599824][ T5890] bridge_slave_0: entered allmulticast mode
[ 65.606225][ T5890] bridge_slave_0: entered promiscuous mode
[ 65.612881][ T5890] bridge0: port 2(bridge_slave_1) entered blocking state
[ 65.619978][ T5890] bridge0: port 2(bridge_slave_1) entered disabled state
[ 65.627492][ T5890] bridge_slave_1: entered allmulticast mode
[ 65.634027][ T5890] bridge_slave_1: entered promiscuous mode
[ 65.645743][ T5890] bond0: (slave bond_slave_0): Enslaving as an active interface with an up link
[ 65.655760][ T5890] bond0: (slave bond_slave_1): Enslaving as an active interface with an up link
[ 65.669914][ T5890] team0: Port device team_slave_0 added
[ 65.676301][ T5890] team0: Port device team_slave_1 added
[ 65.686571][ T5890] batman_adv: batadv0: Adding interface: batadv_slave_0
[ 65.693917][ T5890] batman_adv: batadv0: The MTU of interface batadv_slave_0 is too small (1500) to handle the transport of batman-adv packets. Packets going over this interface will be fragmented on layer2 which could impact the performance. Setting the MTU to 1532 would solve the problem.
[ 65.720230][ T5890] batman_adv: batadv0: Not using interface batadv_slave_0 (retrying later): interface not active
[ 65.731988][ T5890] batman_adv: batadv0: Adding interface: batadv_slave_1
[ 65.739356][ T5890] batman_adv: batadv0: The MTU of interface batadv_slave_1 is too small (1500) to handle the transport of batman-adv packets. Packets going over this interface will be fragmented on layer2 which could impact the performance. Setting the MTU to 1532 would solve the problem.
[ 65.766444][ T5890] batman_adv: batadv0: Not using interface batadv_slave_1 (retrying later): interface not active
[ 65.787487][ T5890] hsr_slave_0: entered promiscuous mode
[ 65.793267][ T5890] hsr_slave_1: entered promiscuous mode
[ 65.822570][ T5890] netdevsim netdevsim0 netdevsim0: renamed from eth0
[ 65.830459][ T5890] netdevsim netdevsim0 netdevsim1: renamed from eth1
[ 65.838351][ T5890] netdevsim netdevsim0 netdevsim2: renamed from eth2
[ 65.846563][ T5890] netdevsim netdevsim0 netdevsim3: renamed from eth3
[ 65.860377][ T5890] bridge0: port 2(bridge_slave_1) entered blocking state
[ 65.867973][ T5890] bridge0: port 2(bridge_slave_1) entered forwarding state
[ 65.875564][ T5890] bridge0: port 1(bridge_slave_0) entered blocking state
[ 65.882626][ T5890] bridge0: port 1(bridge_slave_0) entered forwarding state
[ 65.899327][ T5890] 8021q: adding VLAN 0 to HW filter on device bond0
[ 65.908810][ T65] bridge0: port 1(bridge_slave_0) entered disabled state
[ 65.916368][ T65] bridge0: port 2(bridge_slave_1) entered disabled state
[ 65.926332][ T5890] 8021q: adding VLAN 0 to HW filter on device team0
[ 65.935247][ T55] bridge0: port 1(bridge_slave_0) entered blocking state
[ 65.942415][ T55] bridge0: port 1(bridge_slave_0) entered forwarding state
[ 65.952498][ T55] bridge0: port 2(bridge_slave_1) entered blocking state
[ 65.959571][ T55] bridge0: port 2(bridge_slave_1) entered forwarding state
[ 66.001572][ T5890] 8021q: adding VLAN 0 to HW filter on device batadv0
[ 66.016258][ T5890] veth0_vlan: entered promiscuous mode
[ 66.023938][ T5890] veth1_vlan: entered promiscuous mode
[ 66.035919][ T5890] veth0_macvtap: entered promiscuous mode
[ 66.043178][ T5890] veth1_macvtap: entered promiscuous mode
[ 66.052173][ T5890] batman_adv: batadv0: Interface activated: batadv_slave_0
[ 66.061801][ T5890] batman_adv: batadv0: Interface activated: batadv_slave_1
[ 66.071356][ T55] netdevsim netdevsim0 netdevsim0: set [1, 0] type 2 family 0 port 6081 - 0
[ 66.081780][ T55] netdevsim netdevsim0 netdevsim1: set [1, 0] type 2 family 0 port 6081 - 0
[ 66.091070][ T55] netdevsim netdevsim0 netdevsim2: set [1, 0] type 2 family 0 port 6081 - 0
[ 66.100260][ T55] netdevsim netdevsim0 netdevsim3: set [1, 0] type 2 family 0 port 6081 - 0
[ 66.142913][ T55] netdevsim netdevsim0 netdevsim3 (unregistering): unset [1, 0] type 2 family 0 port 6081 - 0
[ 66.164181][ T31] wlan0: Created IBSS using preconfigured BSSID 50:50:50:50:50:50
[ 66.172643][ T31] wlan0: Creating new IBSS network, BSSID 50:50:50:50:50:50
[ 66.182052][ T55] netdevsim netdevsim0 netdevsim2 (unregistering): unset [1, 0] type 2 family 0 port 6081 - 0
[ 66.195368][ T31] wlan1: Created IBSS using preconfigured BSSID 50:50:50:50:50:50
[ 66.203729][ T31] wlan1: Creating new IBSS network, BSSID 50:50:50:50:50:50
[ 66.230379][ T55] netdevsim netdevsim0 netdevsim1 (unregistering): unset [1, 0] type 2 family 0 port 6081 - 0
[ 66.280211][ T55] netdevsim netdevsim0 netdevsim0 (unregistering): unset [1, 0] type 2 family 0 port 6081 - 0
2025/12/05 19:05:28 executed programs: 0
[ 69.506006][ T55] bridge_slave_1: left allmulticast mode
[ 69.511800][ T55] bridge_slave_1: left promiscuous mode
[ 69.517491][ T55] bridge0: port 2(bridge_slave_1) entered disabled state
[ 69.525504][ T55] bridge_slave_0: left allmulticast mode
[ 69.531369][ T55] bridge_slave_0: left promiscuous mode
[ 69.537068][ T55] bridge0: port 1(bridge_slave_0) entered disabled state
[ 69.601288][ T55] bond0 (unregistering): (slave bond_slave_0): Releasing backup interface
[ 69.611079][ T55] bond0 (unregistering): (slave bond_slave_1): Releasing backup interface
[ 69.620253][ T55] bond0 (unregistering): Released all slaves
[ 69.670943][ T55] hsr_slave_0: left promiscuous mode
[ 69.676955][ T55] hsr_slave_1: left promiscuous mode
[ 69.682958][ T55] batman_adv: batadv0: Interface deactivated: batadv_slave_0
[ 69.691003][ T55] batman_adv: batadv0: Removing interface: batadv_slave_0
[ 69.698476][ T55] batman_adv: batadv0: Interface deactivated: batadv_slave_1
[ 69.706532][ T55] batman_adv: batadv0: Removing interface: batadv_slave_1
[ 69.715577][ T55] veth1_macvtap: left promiscuous mode
[ 69.721203][ T55] veth0_macvtap: left promiscuous mode
[ 69.726728][ T55] veth1_vlan: left promiscuous mode
[ 69.732096][ T55] veth0_vlan: left promiscuous mode
[ 69.757386][ T55] team0 (unregistering): Port device team_slave_1 removed
[ 69.766234][ T55] team0 (unregistering): Port device team_slave_0 removed
[ 70.169404][ T1309] ieee802154 phy0 wpan0: encryption failed: -22
[ 70.175683][ T1309] ieee802154 phy1 wpan1: encryption failed: -22
[ 72.047051][ T5134] Bluetooth: hci0: unexpected cc 0x0c03 length: 249 > 1
[ 72.054869][ T5134] Bluetooth: hci0: unexpected cc 0x1003 length: 249 > 9
[ 72.062046][ T5134] Bluetooth: hci0: unexpected cc 0x1001 length: 249 > 9
[ 72.070042][ T5134] Bluetooth: hci0: unexpected cc 0x0c23 length: 249 > 4
[ 72.077520][ T5134] Bluetooth: hci0: unexpected cc 0x0c38 length: 249 > 2
[ 72.113196][ T5989] chnl_net:caif_netlink_parms(): no params data found
[ 72.132758][ T5989] bridge0: port 1(bridge_slave_0) entered blocking state
[ 72.140022][ T5989] bridge0: port 1(bridge_slave_0) entered disabled state
[ 72.147223][ T5989] bridge_slave_0: entered allmulticast mode
[ 72.153712][ T5989] bridge_slave_0: entered promiscuous mode
[ 72.160489][ T5989] bridge0: port 2(bridge_slave_1) entered blocking state
[ 72.167745][ T5989] bridge0: port 2(bridge_slave_1) entered disabled state
[ 72.174993][ T5989] bridge_slave_1: entered allmulticast mode
[ 72.181245][ T5989] bridge_slave_1: entered promiscuous mode
[ 72.192621][ T5989] bond0: (slave bond_slave_0): Enslaving as an active interface with an up link
[ 72.202629][ T5989] bond0: (slave bond_slave_1): Enslaving as an active interface with an up link
[ 72.217391][ T5989] team0: Port device team_slave_0 added
[ 72.224120][ T5989] team0: Port device team_slave_1 added
[ 72.234181][ T5989] batman_adv: batadv0: Adding interface: batadv_slave_0
[ 72.241867][ T5989] batman_adv: batadv0: The MTU of interface batadv_slave_0 is too small (1500) to handle the transport of batman-adv packets. Packets going over this interface will be fragmented on layer2 which could impact the performance. Setting the MTU to 1532 would solve the problem.
[ 72.268532][ T5989] batman_adv: batadv0: Not using interface batadv_slave_0 (retrying later): interface not active
[ 72.280051][ T5989] batman_adv: batadv0: Adding interface: batadv_slave_1
[ 72.287416][ T5989] batman_adv: batadv0: The MTU of interface batadv_slave_1 is too small (1500) to handle the transport of batman-adv packets. Packets going over this interface will be fragmented on layer2 which could impact the performance. Setting the MTU to 1532 would solve the problem.
[ 72.314180][ T5989] batman_adv: batadv0: Not using interface batadv_slave_1 (retrying later): interface not active
[ 72.331466][ T5989] hsr_slave_0: entered promiscuous mode
[ 72.337615][ T5989] hsr_slave_1: entered promiscuous mode
[ 72.513584][ T5989] netdevsim netdevsim0 netdevsim0: renamed from eth0
[ 72.521437][ T5989] netdevsim netdevsim0 netdevsim1: renamed from eth1
[ 72.529452][ T5989] netdevsim netdevsim0 netdevsim2: renamed from eth2
[ 72.537435][ T5989] netdevsim netdevsim0 netdevsim3: renamed from eth3
[ 72.551368][ T5989] bridge0: port 2(bridge_slave_1) entered blocking state
[ 72.558478][ T5989] bridge0: port 2(bridge_slave_1) entered forwarding state
[ 72.565936][ T5989] bridge0: port 1(bridge_slave_0) entered blocking state
[ 72.573710][ T5989] bridge0: port 1(bridge_slave_0) entered forwarding state
[ 72.596776][ T5989] 8021q: adding VLAN 0 to HW filter on device bond0
[ 72.606884][ T31] bridge0: port 1(bridge_slave_0) entered disabled state
[ 72.615077][ T31] bridge0: port 2(bridge_slave_1) entered disabled state
[ 72.625976][ T5989] 8021q: adding VLAN 0 to HW filter on device team0
[ 72.634865][ T31] bridge0: port 1(bridge_slave_0) entered blocking state
[ 72.642139][ T31] bridge0: port 1(bridge_slave_0) entered forwarding state
[ 72.660348][ T31] bridge0: port 2(bridge_slave_1) entered blocking state
[ 72.667635][ T31] bridge0: port 2(bridge_slave_1) entered forwarding state
[ 72.717525][ T5989] 8021q: adding VLAN 0 to HW filter on device batadv0
[ 72.736386][ T5989] veth0_vlan: entered promiscuous mode
[ 72.743922][ T5989] veth1_vlan: entered promiscuous mode
[ 72.757219][ T5989] veth0_macvtap: entered promiscuous mode
[ 72.764388][ T5989] veth1_macvtap: entered promiscuous mode
[ 72.774941][ T5989] batman_adv: batadv0: Interface activated: batadv_slave_0
[ 72.784711][ T5989] batman_adv: batadv0: Interface activated: batadv_slave_1
[ 72.794630][ T35] netdevsim netdevsim0 netdevsim0: set [1, 0] type 2 family 0 port 6081 - 0
[ 72.807307][ T35] netdevsim netdevsim0 netdevsim1: set [1, 0] type 2 family 0 port 6081 - 0
[ 72.816371][ T723] netdevsim netdevsim0 netdevsim2: set [1, 0] type 2 family 0 port 6081 - 0
[ 72.828572][ T723] netdevsim netdevsim0 netdevsim3: set [1, 0] type 2 family 0 port 6081 - 0
[ 72.847366][ T35] wlan0: Created IBSS using preconfigured BSSID 50:50:50:50:50:50
[ 72.856762][ T35] wlan0: Creating new IBSS network, BSSID 50:50:50:50:50:50
SYZFAIL: failed to recv rpc
fd=3 want=4 recv=0 n=0 (errno 9: Bad file descriptor)
[ 72.870318][ T723] wlan1: Created IBSS using preconfigured BSSID 50:50:50:50:50:50
[ 72.878614][ T723] wlan1: Creating new IBSS network, BSSID 50:50:50:50:50:50
syzkaller build log:
go env (err=<nil>)
AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE='auto'
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/syzkaller/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/syzkaller/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build1479309889=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/syzkaller/jobs-2/linux/gopath/src/github.com/google/syzkaller/go.mod'
GOMODCACHE='/syzkaller/jobs-2/linux/gopath/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/syzkaller/jobs-2/linux/gopath'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/syzkaller/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.24.4'
GOWORK=''
PKG_CONFIG='pkg-config'
git status (err=<nil>)
HEAD detached at d6526ea3e
nothing to commit, working tree clean
tput: No value for $TERM and no -T specified
tput: No value for $TERM and no -T specified
Makefile:31: run command via tools/syz-env for best compatibility, see:
Makefile:32: https://github.com/google/syzkaller/blob/master/docs/contributing.md#using-syz-env
go list -f '{{.Stale}}' -ldflags="-s -w -X github.com/google/syzkaller/prog.GitRevision=d6526ea3e6ad9081c902859bbb80f9f840377cb4 -X github.com/google/syzkaller/prog.gitRevisionDate=20251126-113115" ./sys/syz-sysgen | grep -q false || go install -ldflags="-s -w -X github.com/google/syzkaller/prog.GitRevision=d6526ea3e6ad9081c902859bbb80f9f840377cb4 -X github.com/google/syzkaller/prog.gitRevisionDate=20251126-113115" ./sys/syz-sysgen
make .descriptions
tput: No value for $TERM and no -T specified
tput: No value for $TERM and no -T specified
Makefile:31: run command via tools/syz-env for best compatibility, see:
Makefile:32: https://github.com/google/syzkaller/blob/master/docs/contributing.md#using-syz-env
bin/syz-sysgen
touch .descriptions
GOOS=linux GOARCH=amd64 go build -ldflags="-s -w -X github.com/google/syzkaller/prog.GitRevision=d6526ea3e6ad9081c902859bbb80f9f840377cb4 -X github.com/google/syzkaller/prog.gitRevisionDate=20251126-113115" -o ./bin/linux_amd64/syz-execprog github.com/google/syzkaller/tools/syz-execprog
mkdir -p ./bin/linux_amd64
g++ -o ./bin/linux_amd64/syz-executor executor/executor.cc \
-m64 -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=16384 -Wno-stringop-overflow -Wno-array-bounds -Wno-format-overflow -Wno-unused-but-set-variable -Wno-unused-command-line-argument -static-pie -std=c++17 -I. -Iexecutor/_include -DGOOS_linux=1 -DGOARCH_amd64=1 \
-DHOSTGOOS_linux=1 -DGIT_REVISION=\"d6526ea3e6ad9081c902859bbb80f9f840377cb4\"
/usr/bin/ld: /tmp/ccXWETje.o: in function `Connection::Connect(char const*, char const*)':
executor.cc:(.text._ZN10Connection7ConnectEPKcS1_[_ZN10Connection7ConnectEPKcS1_]+0x104): warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
./tools/check-syzos.sh 2>/dev/null
Tested on:
commit: e69c7c17 Merge tag 'timers_urgent_for_v6.18_rc8' of gi..
git tree: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel config: https://syzkaller.appspot.com/x/.config?x=f30cc590c4f6da44
dashboard link: https://syzkaller.appspot.com/bug?extid=99f6ed51479b86ac4c41
compiler: gcc (Debian 12.2.0-14+deb12u1) 12.2.0, GNU ld (GNU Binutils for Debian) 2.40
patch: https://syzkaller.appspot.com/x/patch.diff?x=14477cc2580000
© 2016 - 2025 Red Hat, Inc.