Re: [PATCH] hfsplus: fix KMSAN: uninit-value in hfsplus_lookup()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Slava,

在 2025/8/5 3:50, Viacheslav Dubeyko 写道:
If Catalog File contains corrupted record for the case of
hidden directory (particularly, entry.folder.id is lesser
than HFSPLUS_FIRSTUSER_CNID), then it can trigger the issue:

[   65.773760][ T9320] BUG: KMSAN: uninit-value in hfsplus_lookup+0xcd7/0x11f0
[   65.774362][ T9320]  hfsplus_lookup+0xcd7/0x11f0
[   65.774756][ T9320]  __lookup_slow+0x525/0x720
[   65.775160][ T9320]  lookup_slow+0x6a/0xd0
[   65.775513][ T9320]  walk_component+0x393/0x680
[   65.775896][ T9320]  path_lookupat+0x257/0x6c0
[   65.776313][ T9320]  filename_lookup+0x2ac/0x800
[   65.776693][ T9320]  user_path_at+0x8f/0x3c0
[   65.777078][ T9320]  __x64_sys_umount+0x146/0x250
[   65.777484][ T9320]  x64_sys_call+0x2806/0x3d90
[   65.777851][ T9320]  do_syscall_64+0xd9/0x1e0
[   65.778263][ T9320]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
[   65.778716][ T9320]
[   65.778906][ T9320] Uninit was created at:
[   65.779294][ T9320]  __alloc_frozen_pages_noprof+0x714/0xe60
[   65.779750][ T9320]  alloc_pages_mpol+0x295/0x890
[   65.780148][ T9320]  alloc_frozen_pages_noprof+0xf8/0x1f0
[   65.780597][ T9320]  allocate_slab+0x216/0x1190
[   65.780961][ T9320]  ___slab_alloc+0x104c/0x33c0
[   65.781543][ T9320]  kmem_cache_alloc_lru_noprof+0x8f6/0xe70
[   65.782135][ T9320]  hfsplus_alloc_inode+0x5a/0xd0
[   65.782608][ T9320]  alloc_inode+0x82/0x490
[   65.783055][ T9320]  iget_locked+0x22e/0x1320
[   65.783495][ T9320]  hfsplus_iget+0xc9/0xd70
[   65.783944][ T9320]  hfsplus_btree_open+0x12b/0x1de0
[   65.784456][ T9320]  hfsplus_fill_super+0xc1c/0x27b0
[   65.784922][ T9320]  get_tree_bdev_flags+0x6e6/0x920
[   65.785403][ T9320]  get_tree_bdev+0x38/0x50
[   65.785819][ T9320]  hfsplus_get_tree+0x35/0x40
[   65.786275][ T9320]  vfs_get_tree+0xb3/0x5c0
[   65.786674][ T9320]  do_new_mount+0x73e/0x1630
[   65.787135][ T9320]  path_mount+0x6e3/0x1eb0
[   65.787564][ T9320]  __se_sys_mount+0x73a/0x830
[   65.787944][ T9320]  __x64_sys_mount+0xe4/0x150
[   65.788346][ T9320]  x64_sys_call+0x3904/0x3d90
[   65.788707][ T9320]  do_syscall_64+0xd9/0x1e0
[   65.789090][ T9320]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
[   65.789557][ T9320]
[   65.789744][ T9320] CPU: 0 UID: 0 PID: 9320 Comm: repro Not tainted 6.14.0-rc5 #5
[   65.790355][ T9320] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[   65.791197][ T9320] =====================================================
[   65.791814][ T9320] Disabling lock debugging due to kernel taint
[   65.792419][ T9320] Kernel panic - not syncing: kmsan.panic set ...
[   65.793000][ T9320] CPU: 0 UID: 0 PID: 9320 Comm: repro Tainted: G    B              6.14.0-rc5 #5
[   65.793830][ T9320] Tainted: [B]=BAD_PAGE
[   65.794235][ T9320] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[   65.795211][ T9320] Call Trace:
[   65.795519][ T9320]  <TASK>
[   65.795797][ T9320]  dump_stack_lvl+0x1fd/0x2b0
[   65.796256][ T9320]  dump_stack+0x1e/0x25
[   65.796677][ T9320]  panic+0x505/0xca0
[   65.797112][ T9320]  ? kmsan_get_metadata+0xf9/0x150
[   65.797625][ T9320]  kmsan_report+0x299/0x2a0
[   65.798105][ T9320]  ? kmsan_internal_unpoison_memory+0x14/0x20
[   65.798696][ T9320]  ? __msan_metadata_ptr_for_load_4+0x24/0x40
[   65.799291][ T9320]  ? __msan_warning+0x96/0x120
[   65.799785][ T9320]  ? hfsplus_lookup+0xcd7/0x11f0
[   65.800294][ T9320]  ? __lookup_slow+0x525/0x720
[   65.800772][ T9320]  ? lookup_slow+0x6a/0xd0
[   65.801239][ T9320]  ? walk_component+0x393/0x680
[   65.801730][ T9320]  ? path_lookupat+0x257/0x6c0
[   65.802225][ T9320]  ? filename_lookup+0x2ac/0x800
[   65.802720][ T9320]  ? user_path_at+0x8f/0x3c0
[   65.803202][ T9320]  ? __x64_sys_umount+0x146/0x250
[   65.803683][ T9320]  ? x64_sys_call+0x2806/0x3d90
[   65.804177][ T9320]  ? do_syscall_64+0xd9/0x1e0
[   65.804634][ T9320]  ? entry_SYSCALL_64_after_hwframe+0x77/0x7f
[   65.805251][ T9320]  ? kmsan_get_metadata+0x70/0x150
[   65.805764][ T9320]  ? vprintk_default+0x3f/0x50
[   65.806256][ T9320]  ? vprintk+0x36/0x50
[   65.806659][ T9320]  ? _printk+0x17e/0x1b0
[   65.807107][ T9320]  ? kmsan_get_metadata+0xf9/0x150
[   65.807621][ T9320]  __msan_warning+0x96/0x120
[   65.808103][ T9320]  hfsplus_lookup+0xcd7/0x11f0
[   65.808587][ T9320]  ? kmsan_get_metadata+0x70/0x150
[   65.809108][ T9320]  ? kmsan_get_metadata+0xf9/0x150
[   65.809627][ T9320]  ? kmsan_get_metadata+0xf9/0x150
[   65.810142][ T9320]  ? __pfx_hfsplus_lookup+0x10/0x10
[   65.810669][ T9320]  ? kmsan_get_shadow_origin_ptr+0x4a/0xb0
[   65.811258][ T9320]  ? __pfx_hfsplus_lookup+0x10/0x10
[   65.811787][ T9320]  __lookup_slow+0x525/0x720
[   65.812258][ T9320]  lookup_slow+0x6a/0xd0
[   65.812700][ T9320]  walk_component+0x393/0x680
[   65.813178][ T9320]  ? kmsan_get_metadata+0xf9/0x150
[   65.813697][ T9320]  path_lookupat+0x257/0x6c0
[   65.814196][ T9320]  filename_lookup+0x2ac/0x800
[   65.814677][ T9320]  ? strncpy_from_user+0x255/0x470
[   65.815193][ T9320]  ? kmsan_get_metadata+0xf9/0x150
[   65.815706][ T9320]  ? kmsan_get_shadow_origin_ptr+0x4a/0xb0
[   65.816290][ T9320]  ? __msan_metadata_ptr_for_load_8+0x24/0x40
[   65.816886][ T9320]  user_path_at+0x8f/0x3c0
[   65.817342][ T9320]  ? __x64_sys_umount+0x6d/0x250
[   65.817834][ T9320]  __x64_sys_umount+0x146/0x250
[   65.818333][ T9320]  ? kmsan_internal_set_shadow_origin+0x79/0x110
[   65.818945][ T9320]  x64_sys_call+0x2806/0x3d90
[   65.819420][ T9320]  do_syscall_64+0xd9/0x1e0
[   65.819876][ T9320]  ? irqentry_exit+0x16/0x60
[   65.820353][ T9320]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
[   65.820951][ T9320] RIP: 0033:0x7f822cb8fb07
[   65.821427][ T9320] Code: 23 0d 00 f7 d8 64 89 01 48 83 c8 ff c3 66 0f 1f 44 00 00 31 f6 e9 09 00 00 00 66 0f 1f 84 00 00 08
[   65.823225][ T9320] RSP: 002b:00007fff4858f038 EFLAGS: 00000202 ORIG_RAX: 00000000000000a6
[   65.824037][ T9320] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f822cb8fb07
[   65.824818][ T9320] RDX: 0000000000000009 RSI: 0000000000000009 RDI: 00007fff4858f0e0
[   65.825568][ T9320] RBP: 00007fff48590120 R08: 00007f822cc23040 R09: 00007fff4858eed0
[   65.826329][ T9320] R10: 00007f822cc22fc0 R11: 0000000000000202 R12: 000055bd891e22d0
[   65.827086][ T9320] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
[   65.827850][ T9320]  </TASK>
[   65.828677][ T9320] Kernel Offset: disabled
[   65.829095][ T9320] Rebooting in 86400 seconds..

It means that if hfsplus_iget() receives inode ID lesser than
HFSPLUS_FIRSTUSER_CNID, then it treats it as system inode and
hfsplus_system_read_inode() will be called. As result,
struct hfsplus_inode_info is not initialized properly for
the case of hidden directory. The hidden directory is the record of
Catalog File and hfsplus_cat_read_inode() should be called
for the proper initalization of hidden directory's inode.

This patch adds checking of entry.folder.id for the case of
hidden directory in hfsplus_fill_super(). The CNID of hidden folder
cannot be lesser than HFSPLUS_FIRSTUSER_CNID. And if we receive
such invalid CNID, then record is corrupted and hfsplus_fill_super()
returns the EIO error. Also, patch adds invalid CNID declaration and
declarations of another reserved CNIDs.

Reported-by: syzbot <syzbot+91db973302e7b18c7653@xxxxxxxxxxxxxxxxxxxxxxxxx>
Closes: https://syzkaller.appspot.com/bug?extid=91db973302e7b18c7653
Signed-off-by: Viacheslav Dubeyko <slava@xxxxxxxxxxx>
cc: John Paul Adrian Glaubitz <glaubitz@xxxxxxxxxxxxxxxxxxx>
cc: Yangtao Li <frank.li@xxxxxxxx>
cc: linux-fsdevel@xxxxxxxxxxxxxxx
---
  fs/hfsplus/hfsplus_raw.h | 7 +++++++
  fs/hfsplus/super.c       | 4 ++++
  2 files changed, 11 insertions(+)

diff --git a/fs/hfsplus/hfsplus_raw.h b/fs/hfsplus/hfsplus_raw.h
index 68b4240c6191..bdd4deab46c6 100644
--- a/fs/hfsplus/hfsplus_raw.h
+++ b/fs/hfsplus/hfsplus_raw.h
@@ -194,6 +194,7 @@ struct hfs_btree_header_rec {
  #define HFSPLUS_BTREE_HDR_USER_BYTES		128
/* Some special File ID numbers (stolen from hfs.h) */
+#define HFSPLUS_INVALID_CNID		0	/* Invalid id */


Could we drop those for this patch?

If they're needed, we can add them in other patches.

I don't see their usage.



  #define HFSPLUS_POR_CNID		1	/* Parent Of the Root */
  #define HFSPLUS_ROOT_CNID		2	/* ROOT directory */
  #define HFSPLUS_EXT_CNID		3	/* EXTents B-tree */
@@ -202,6 +203,12 @@ struct hfs_btree_header_rec {
  #define HFSPLUS_ALLOC_CNID		6	/* ALLOCation file */
  #define HFSPLUS_START_CNID		7	/* STARTup file */
  #define HFSPLUS_ATTR_CNID		8	/* ATTRibutes file */
+#define HFSPLUS_RESERVED_CNID_9		9
+#define HFSPLUS_RESERVED_CNID_10	10
+#define HFSPLUS_RESERVED_CNID_11	11
+#define HFSPLUS_RESERVED_CNID_12	12
+#define HFSPLUS_RESERVED_CNID_13	13
+#define HFSPLUS_REPAIR_CAT_CNID		14	/* Repair CATalog File id */


Same.


  #define HFSPLUS_EXCH_CNID		15	/* ExchangeFiles temp id */
  #define HFSPLUS_FIRSTUSER_CNID		16	/* first available user id */
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index 86351bdc8985..8f2790a78e08 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -527,6 +527,10 @@ static int hfsplus_fill_super(struct super_block *sb, struct fs_context *fc)
  			err = -EINVAL;
  			goto out_put_root;
  		}
+		if (be32_to_cpu(entry.folder.id) < HFSPLUS_FIRSTUSER_CNID) {
+			err = -EIO;
+			goto out_put_root;
+		}


Otherwise, LGTM.

Reviewed-by: Yangtao Li <frank.li <http://frank.li/>@vivo.com <http://vivo.com/>>

Thx,

Yangtao





[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux