linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] hfsplus: fix slab-out-of-bounds read in hfsplus_uni2asc()
@ 2025-07-03 18:41 Viacheslav Dubeyko
  2025-07-09  5:10 ` Yangtao Li
  0 siblings, 1 reply; 6+ messages in thread
From: Viacheslav Dubeyko @ 2025-07-03 18:41 UTC (permalink / raw)
  To: glaubitz, linux-fsdevel, frank.li, wenzhi.wang
  Cc: Slava.Dubeyko, Viacheslav Dubeyko

The hfsplus_readdir() method is capable to crash by calling
hfsplus_uni2asc():

[  667.121659][ T9805] ==================================================================
[  667.122651][ T9805] BUG: KASAN: slab-out-of-bounds in hfsplus_uni2asc+0x902/0xa10
[  667.123627][ T9805] Read of size 2 at addr ffff88802592f40c by task repro/9805
[  667.124578][ T9805]
[  667.124876][ T9805] CPU: 3 UID: 0 PID: 9805 Comm: repro Not tainted 6.16.0-rc3 #1 PREEMPT(full)
[  667.124886][ T9805] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[  667.124890][ T9805] Call Trace:
[  667.124893][ T9805]  <TASK>
[  667.124896][ T9805]  dump_stack_lvl+0x10e/0x1f0
[  667.124911][ T9805]  print_report+0xd0/0x660
[  667.124920][ T9805]  ? __virt_addr_valid+0x81/0x610
[  667.124928][ T9805]  ? __phys_addr+0xe8/0x180
[  667.124934][ T9805]  ? hfsplus_uni2asc+0x902/0xa10
[  667.124942][ T9805]  kasan_report+0xc6/0x100
[  667.124950][ T9805]  ? hfsplus_uni2asc+0x902/0xa10
[  667.124959][ T9805]  hfsplus_uni2asc+0x902/0xa10
[  667.124966][ T9805]  ? hfsplus_bnode_read+0x14b/0x360
[  667.124974][ T9805]  hfsplus_readdir+0x845/0xfc0
[  667.124984][ T9805]  ? __pfx_hfsplus_readdir+0x10/0x10
[  667.124994][ T9805]  ? stack_trace_save+0x8e/0xc0
[  667.125008][ T9805]  ? iterate_dir+0x18b/0xb20
[  667.125015][ T9805]  ? trace_lock_acquire+0x85/0xd0
[  667.125022][ T9805]  ? lock_acquire+0x30/0x80
[  667.125029][ T9805]  ? iterate_dir+0x18b/0xb20
[  667.125037][ T9805]  ? down_read_killable+0x1ed/0x4c0
[  667.125044][ T9805]  ? putname+0x154/0x1a0
[  667.125051][ T9805]  ? __pfx_down_read_killable+0x10/0x10
[  667.125058][ T9805]  ? apparmor_file_permission+0x239/0x3e0
[  667.125069][ T9805]  iterate_dir+0x296/0xb20
[  667.125076][ T9805]  __x64_sys_getdents64+0x13c/0x2c0
[  667.125084][ T9805]  ? __pfx___x64_sys_getdents64+0x10/0x10
[  667.125091][ T9805]  ? __x64_sys_openat+0x141/0x200
[  667.125126][ T9805]  ? __pfx_filldir64+0x10/0x10
[  667.125134][ T9805]  ? do_user_addr_fault+0x7fe/0x12f0
[  667.125143][ T9805]  do_syscall_64+0xc9/0x480
[  667.125151][ T9805]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
[  667.125158][ T9805] RIP: 0033:0x7fa8753b2fc9
[  667.125164][ T9805] Code: 00 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 48
[  667.125172][ T9805] RSP: 002b:00007ffe96f8e0f8 EFLAGS: 00000217 ORIG_RAX: 00000000000000d9
[  667.125181][ T9805] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fa8753b2fc9
[  667.125185][ T9805] RDX: 0000000000000400 RSI: 00002000000063c0 RDI: 0000000000000004
[  667.125190][ T9805] RBP: 00007ffe96f8e110 R08: 00007ffe96f8e110 R09: 00007ffe96f8e110
[  667.125195][ T9805] R10: 0000000000000000 R11: 0000000000000217 R12: 0000556b1e3b4260
[  667.125199][ T9805] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
[  667.125207][ T9805]  </TASK>
[  667.125210][ T9805]
[  667.145632][ T9805] Allocated by task 9805:
[  667.145991][ T9805]  kasan_save_stack+0x20/0x40
[  667.146352][ T9805]  kasan_save_track+0x14/0x30
[  667.146717][ T9805]  __kasan_kmalloc+0xaa/0xb0
[  667.147065][ T9805]  __kmalloc_noprof+0x205/0x550
[  667.147448][ T9805]  hfsplus_find_init+0x95/0x1f0
[  667.147813][ T9805]  hfsplus_readdir+0x220/0xfc0
[  667.148174][ T9805]  iterate_dir+0x296/0xb20
[  667.148549][ T9805]  __x64_sys_getdents64+0x13c/0x2c0
[  667.148937][ T9805]  do_syscall_64+0xc9/0x480
[  667.149291][ T9805]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
[  667.149809][ T9805]
[  667.150030][ T9805] The buggy address belongs to the object at ffff88802592f000
[  667.150030][ T9805]  which belongs to the cache kmalloc-2k of size 2048
[  667.151282][ T9805] The buggy address is located 0 bytes to the right of
[  667.151282][ T9805]  allocated 1036-byte region [ffff88802592f000, ffff88802592f40c)
[  667.152580][ T9805]
[  667.152798][ T9805] The buggy address belongs to the physical page:
[  667.153373][ T9805] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x25928
[  667.154157][ T9805] head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
[  667.154916][ T9805] anon flags: 0xfff00000000040(head|node=0|zone=1|lastcpupid=0x7ff)
[  667.155631][ T9805] page_type: f5(slab)
[  667.155997][ T9805] raw: 00fff00000000040 ffff88801b442f00 0000000000000000 dead000000000001
[  667.156770][ T9805] raw: 0000000000000000 0000000080080008 00000000f5000000 0000000000000000
[  667.157536][ T9805] head: 00fff00000000040 ffff88801b442f00 0000000000000000 dead000000000001
[  667.158317][ T9805] head: 0000000000000000 0000000080080008 00000000f5000000 0000000000000000
[  667.159088][ T9805] head: 00fff00000000003 ffffea0000964a01 00000000ffffffff 00000000ffffffff
[  667.159865][ T9805] head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000008
[  667.160643][ T9805] page dumped because: kasan: bad access detected
[  667.161216][ T9805] page_owner tracks the page as allocated
[  667.161732][ T9805] page last allocated via order 3, migratetype Unmovable, gfp_mask 0xd20c0(__GFP_IO|__GFP_FS|__GFP_NOWARN9
[  667.163566][ T9805]  post_alloc_hook+0x1c0/0x230
[  667.164003][ T9805]  get_page_from_freelist+0xdeb/0x3b30
[  667.164503][ T9805]  __alloc_frozen_pages_noprof+0x25c/0x2460
[  667.165040][ T9805]  alloc_pages_mpol+0x1fb/0x550
[  667.165489][ T9805]  new_slab+0x23b/0x340
[  667.165872][ T9805]  ___slab_alloc+0xd81/0x1960
[  667.166313][ T9805]  __slab_alloc.isra.0+0x56/0xb0
[  667.166767][ T9805]  __kmalloc_cache_noprof+0x255/0x3e0
[  667.167255][ T9805]  psi_cgroup_alloc+0x52/0x2d0
[  667.167693][ T9805]  cgroup_mkdir+0x694/0x1210
[  667.168118][ T9805]  kernfs_iop_mkdir+0x111/0x190
[  667.168568][ T9805]  vfs_mkdir+0x59b/0x8d0
[  667.168956][ T9805]  do_mkdirat+0x2ed/0x3d0
[  667.169353][ T9805]  __x64_sys_mkdir+0xef/0x140
[  667.169784][ T9805]  do_syscall_64+0xc9/0x480
[  667.170195][ T9805]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
[  667.170730][ T9805] page last free pid 1257 tgid 1257 stack trace:
[  667.171304][ T9805]  __free_frozen_pages+0x80c/0x1250
[  667.171770][ T9805]  vfree.part.0+0x12b/0xab0
[  667.172182][ T9805]  delayed_vfree_work+0x93/0xd0
[  667.172612][ T9805]  process_one_work+0x9b5/0x1b80
[  667.173067][ T9805]  worker_thread+0x630/0xe60
[  667.173486][ T9805]  kthread+0x3a8/0x770
[  667.173857][ T9805]  ret_from_fork+0x517/0x6e0
[  667.174278][ T9805]  ret_from_fork_asm+0x1a/0x30
[  667.174703][ T9805]
[  667.174917][ T9805] Memory state around the buggy address:
[  667.175411][ T9805]  ffff88802592f300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[  667.176114][ T9805]  ffff88802592f380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[  667.176830][ T9805] >ffff88802592f400: 00 04 fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[  667.177547][ T9805]                       ^
[  667.177933][ T9805]  ffff88802592f480: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[  667.178640][ T9805]  ffff88802592f500: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[  667.179350][ T9805] ==================================================================

The hfsplus_uni2asc() method operates by struct hfsplus_unistr:

struct hfsplus_unistr {
	__be16 length;
	hfsplus_unichr unicode[HFSPLUS_MAX_STRLEN];
} __packed;

where HFSPLUS_MAX_STRLEN is 255 bytes. The issue happens if length
of the structure instance has value bigger than 255 (for example,
65283). In such case, pointer on unicode buffer is going beyond of
the allocated memory.

The patch fixes the issue by checking the length value of
hfsplus_unistr instance and using 255 value in the case if length
value is bigger than HFSPLUS_MAX_STRLEN. Potential reason of such
situation could be a corruption of Catalog File b-tree's node.

Reported-by: Wenzhi Wang <wenzhi.wang@uwaterloo.ca>
Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
---
 fs/hfsplus/unicode.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/fs/hfsplus/unicode.c b/fs/hfsplus/unicode.c
index 73342c925a4b..7e62b3630fcd 100644
--- a/fs/hfsplus/unicode.c
+++ b/fs/hfsplus/unicode.c
@@ -132,7 +132,11 @@ int hfsplus_uni2asc(struct super_block *sb,
 
 	op = astr;
 	ip = ustr->unicode;
+
 	ustrlen = be16_to_cpu(ustr->length);
+	if (ustrlen > HFSPLUS_MAX_STRLEN)
+		ustrlen = HFSPLUS_MAX_STRLEN;
+
 	len = *len_p;
 	ce1 = NULL;
 	compose = !test_bit(HFSPLUS_SB_NODECOMPOSE, &HFSPLUS_SB(sb)->flags);
-- 
2.43.0


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

* Re: [PATCH] hfsplus: fix slab-out-of-bounds read in hfsplus_uni2asc()
  2025-07-03 18:41 Viacheslav Dubeyko
@ 2025-07-09  5:10 ` Yangtao Li
  2025-07-09 18:19   ` Viacheslav Dubeyko
  0 siblings, 1 reply; 6+ messages in thread
From: Yangtao Li @ 2025-07-09  5:10 UTC (permalink / raw)
  To: Viacheslav Dubeyko, glaubitz, linux-fsdevel, wenzhi.wang; +Cc: Slava.Dubeyko

Hi Slava,

在 2025/7/4 02:41, Viacheslav Dubeyko 写道:
> The hfsplus_readdir() method is capable to crash by calling
> hfsplus_uni2asc():
> 
> [  667.121659][ T9805] ==================================================================
> [  667.122651][ T9805] BUG: KASAN: slab-out-of-bounds in hfsplus_uni2asc+0x902/0xa10
> [  667.123627][ T9805] Read of size 2 at addr ffff88802592f40c by task repro/9805
> [  667.124578][ T9805]
> [  667.124876][ T9805] CPU: 3 UID: 0 PID: 9805 Comm: repro Not tainted 6.16.0-rc3 #1 PREEMPT(full)
> [  667.124886][ T9805] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
> [  667.124890][ T9805] Call Trace:
> [  667.124893][ T9805]  <TASK>
> [  667.124896][ T9805]  dump_stack_lvl+0x10e/0x1f0
> [  667.124911][ T9805]  print_report+0xd0/0x660
> [  667.124920][ T9805]  ? __virt_addr_valid+0x81/0x610
> [  667.124928][ T9805]  ? __phys_addr+0xe8/0x180
> [  667.124934][ T9805]  ? hfsplus_uni2asc+0x902/0xa10
> [  667.124942][ T9805]  kasan_report+0xc6/0x100
> [  667.124950][ T9805]  ? hfsplus_uni2asc+0x902/0xa10
> [  667.124959][ T9805]  hfsplus_uni2asc+0x902/0xa10
> [  667.124966][ T9805]  ? hfsplus_bnode_read+0x14b/0x360
> [  667.124974][ T9805]  hfsplus_readdir+0x845/0xfc0
> [  667.124984][ T9805]  ? __pfx_hfsplus_readdir+0x10/0x10
> [  667.124994][ T9805]  ? stack_trace_save+0x8e/0xc0
> [  667.125008][ T9805]  ? iterate_dir+0x18b/0xb20
> [  667.125015][ T9805]  ? trace_lock_acquire+0x85/0xd0
> [  667.125022][ T9805]  ? lock_acquire+0x30/0x80
> [  667.125029][ T9805]  ? iterate_dir+0x18b/0xb20
> [  667.125037][ T9805]  ? down_read_killable+0x1ed/0x4c0
> [  667.125044][ T9805]  ? putname+0x154/0x1a0
> [  667.125051][ T9805]  ? __pfx_down_read_killable+0x10/0x10
> [  667.125058][ T9805]  ? apparmor_file_permission+0x239/0x3e0
> [  667.125069][ T9805]  iterate_dir+0x296/0xb20
> [  667.125076][ T9805]  __x64_sys_getdents64+0x13c/0x2c0
> [  667.125084][ T9805]  ? __pfx___x64_sys_getdents64+0x10/0x10
> [  667.125091][ T9805]  ? __x64_sys_openat+0x141/0x200
> [  667.125126][ T9805]  ? __pfx_filldir64+0x10/0x10
> [  667.125134][ T9805]  ? do_user_addr_fault+0x7fe/0x12f0
> [  667.125143][ T9805]  do_syscall_64+0xc9/0x480
> [  667.125151][ T9805]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
> [  667.125158][ T9805] RIP: 0033:0x7fa8753b2fc9
> [  667.125164][ T9805] Code: 00 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 48
> [  667.125172][ T9805] RSP: 002b:00007ffe96f8e0f8 EFLAGS: 00000217 ORIG_RAX: 00000000000000d9
> [  667.125181][ T9805] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fa8753b2fc9
> [  667.125185][ T9805] RDX: 0000000000000400 RSI: 00002000000063c0 RDI: 0000000000000004
> [  667.125190][ T9805] RBP: 00007ffe96f8e110 R08: 00007ffe96f8e110 R09: 00007ffe96f8e110
> [  667.125195][ T9805] R10: 0000000000000000 R11: 0000000000000217 R12: 0000556b1e3b4260
> [  667.125199][ T9805] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
> [  667.125207][ T9805]  </TASK>
> [  667.125210][ T9805]
> [  667.145632][ T9805] Allocated by task 9805:
> [  667.145991][ T9805]  kasan_save_stack+0x20/0x40
> [  667.146352][ T9805]  kasan_save_track+0x14/0x30
> [  667.146717][ T9805]  __kasan_kmalloc+0xaa/0xb0
> [  667.147065][ T9805]  __kmalloc_noprof+0x205/0x550
> [  667.147448][ T9805]  hfsplus_find_init+0x95/0x1f0
> [  667.147813][ T9805]  hfsplus_readdir+0x220/0xfc0
> [  667.148174][ T9805]  iterate_dir+0x296/0xb20
> [  667.148549][ T9805]  __x64_sys_getdents64+0x13c/0x2c0
> [  667.148937][ T9805]  do_syscall_64+0xc9/0x480
> [  667.149291][ T9805]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
> [  667.149809][ T9805]
> [  667.150030][ T9805] The buggy address belongs to the object at ffff88802592f000
> [  667.150030][ T9805]  which belongs to the cache kmalloc-2k of size 2048
> [  667.151282][ T9805] The buggy address is located 0 bytes to the right of
> [  667.151282][ T9805]  allocated 1036-byte region [ffff88802592f000, ffff88802592f40c)
> [  667.152580][ T9805]
> [  667.152798][ T9805] The buggy address belongs to the physical page:
> [  667.153373][ T9805] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x25928
> [  667.154157][ T9805] head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
> [  667.154916][ T9805] anon flags: 0xfff00000000040(head|node=0|zone=1|lastcpupid=0x7ff)
> [  667.155631][ T9805] page_type: f5(slab)
> [  667.155997][ T9805] raw: 00fff00000000040 ffff88801b442f00 0000000000000000 dead000000000001
> [  667.156770][ T9805] raw: 0000000000000000 0000000080080008 00000000f5000000 0000000000000000
> [  667.157536][ T9805] head: 00fff00000000040 ffff88801b442f00 0000000000000000 dead000000000001
> [  667.158317][ T9805] head: 0000000000000000 0000000080080008 00000000f5000000 0000000000000000
> [  667.159088][ T9805] head: 00fff00000000003 ffffea0000964a01 00000000ffffffff 00000000ffffffff
> [  667.159865][ T9805] head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000008
> [  667.160643][ T9805] page dumped because: kasan: bad access detected
> [  667.161216][ T9805] page_owner tracks the page as allocated
> [  667.161732][ T9805] page last allocated via order 3, migratetype Unmovable, gfp_mask 0xd20c0(__GFP_IO|__GFP_FS|__GFP_NOWARN9
> [  667.163566][ T9805]  post_alloc_hook+0x1c0/0x230
> [  667.164003][ T9805]  get_page_from_freelist+0xdeb/0x3b30
> [  667.164503][ T9805]  __alloc_frozen_pages_noprof+0x25c/0x2460
> [  667.165040][ T9805]  alloc_pages_mpol+0x1fb/0x550
> [  667.165489][ T9805]  new_slab+0x23b/0x340
> [  667.165872][ T9805]  ___slab_alloc+0xd81/0x1960
> [  667.166313][ T9805]  __slab_alloc.isra.0+0x56/0xb0
> [  667.166767][ T9805]  __kmalloc_cache_noprof+0x255/0x3e0
> [  667.167255][ T9805]  psi_cgroup_alloc+0x52/0x2d0
> [  667.167693][ T9805]  cgroup_mkdir+0x694/0x1210
> [  667.168118][ T9805]  kernfs_iop_mkdir+0x111/0x190
> [  667.168568][ T9805]  vfs_mkdir+0x59b/0x8d0
> [  667.168956][ T9805]  do_mkdirat+0x2ed/0x3d0
> [  667.169353][ T9805]  __x64_sys_mkdir+0xef/0x140
> [  667.169784][ T9805]  do_syscall_64+0xc9/0x480
> [  667.170195][ T9805]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
> [  667.170730][ T9805] page last free pid 1257 tgid 1257 stack trace:
> [  667.171304][ T9805]  __free_frozen_pages+0x80c/0x1250
> [  667.171770][ T9805]  vfree.part.0+0x12b/0xab0
> [  667.172182][ T9805]  delayed_vfree_work+0x93/0xd0
> [  667.172612][ T9805]  process_one_work+0x9b5/0x1b80
> [  667.173067][ T9805]  worker_thread+0x630/0xe60
> [  667.173486][ T9805]  kthread+0x3a8/0x770
> [  667.173857][ T9805]  ret_from_fork+0x517/0x6e0
> [  667.174278][ T9805]  ret_from_fork_asm+0x1a/0x30
> [  667.174703][ T9805]
> [  667.174917][ T9805] Memory state around the buggy address:
> [  667.175411][ T9805]  ffff88802592f300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> [  667.176114][ T9805]  ffff88802592f380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> [  667.176830][ T9805] >ffff88802592f400: 00 04 fc fc fc fc fc fc fc fc fc fc fc fc fc fc
> [  667.177547][ T9805]                       ^
> [  667.177933][ T9805]  ffff88802592f480: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
> [  667.178640][ T9805]  ffff88802592f500: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
> [  667.179350][ T9805] ==================================================================
> 
> The hfsplus_uni2asc() method operates by struct hfsplus_unistr:
> 
> struct hfsplus_unistr {
> 	__be16 length;
> 	hfsplus_unichr unicode[HFSPLUS_MAX_STRLEN];
> } __packed;
> 
> where HFSPLUS_MAX_STRLEN is 255 bytes. The issue happens if length
> of the structure instance has value bigger than 255 (for example,
> 65283). In such case, pointer on unicode buffer is going beyond of
> the allocated memory.
> 
> The patch fixes the issue by checking the length value of
> hfsplus_unistr instance and using 255 value in the case if length
> value is bigger than HFSPLUS_MAX_STRLEN. Potential reason of such
> situation could be a corruption of Catalog File b-tree's node.
> 
> Reported-by: Wenzhi Wang <wenzhi.wang@uwaterloo.ca>
> Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
> ---
>   fs/hfsplus/unicode.c | 4 ++++
>   1 file changed, 4 insertions(+)
> 
> diff --git a/fs/hfsplus/unicode.c b/fs/hfsplus/unicode.c
> index 73342c925a4b..7e62b3630fcd 100644
> --- a/fs/hfsplus/unicode.c
> +++ b/fs/hfsplus/unicode.c
> @@ -132,7 +132,11 @@ int hfsplus_uni2asc(struct super_block *sb,
>   
>   	op = astr;
>   	ip = ustr->unicode;
> +
>   	ustrlen = be16_to_cpu(ustr->length);
> +	if (ustrlen > HFSPLUS_MAX_STRLEN)
> +		ustrlen = HFSPLUS_MAX_STRLEN;
> +
>   	len = *len_p;
>   	ce1 = NULL;
>   	compose = !test_bit(HFSPLUS_SB_NODECOMPOSE, &HFSPLUS_SB(sb)->flags);

I found that Liu Shixin already sent a similar patch [1].

 From [2], Long file names for hfsplus is 255 characters.

Could we mark it as EIO?

[1]
https://lore.kernel.org/all/20221129023949.4186612-1-liushixin2@huawei.com/
[2]
https://dubeyko.com/development/FileSystems/HFSPLUS/tn1150.html#HFSPlusBasics

Thx,
Yangtao

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

* Re: [PATCH] hfsplus: fix slab-out-of-bounds read in hfsplus_uni2asc()
  2025-07-09  5:10 ` Yangtao Li
@ 2025-07-09 18:19   ` Viacheslav Dubeyko
  0 siblings, 0 replies; 6+ messages in thread
From: Viacheslav Dubeyko @ 2025-07-09 18:19 UTC (permalink / raw)
  To: Yangtao Li, glaubitz, linux-fsdevel, wenzhi.wang; +Cc: Slava.Dubeyko

On Wed, 2025-07-09 at 13:10 +0800, Yangtao Li wrote:
> Hi Slava,
> 
> 在 2025/7/4 02:41, Viacheslav Dubeyko 写道:
> > The hfsplus_readdir() method is capable to crash by calling
> > hfsplus_uni2asc():
> > 
> > [  667.121659][ T9805]
> > ==================================================================
> > [  667.122651][ T9805] BUG: KASAN: slab-out-of-bounds in
> > hfsplus_uni2asc+0x902/0xa10
> > [  667.123627][ T9805] Read of size 2 at addr ffff88802592f40c by
> > task repro/9805
> > [  667.124578][ T9805]
> > [  667.124876][ T9805] CPU: 3 UID: 0 PID: 9805 Comm: repro Not
> > tainted 6.16.0-rc3 #1 PREEMPT(full)
> > [  667.124886][ T9805] Hardware name: QEMU Ubuntu 24.04 PC (i440FX
> > + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
> > [  667.124890][ T9805] Call Trace:
> > [  667.124893][ T9805]  <TASK>
> > [  667.124896][ T9805]  dump_stack_lvl+0x10e/0x1f0
> > [  667.124911][ T9805]  print_report+0xd0/0x660
> > [  667.124920][ T9805]  ? __virt_addr_valid+0x81/0x610
> > [  667.124928][ T9805]  ? __phys_addr+0xe8/0x180
> > [  667.124934][ T9805]  ? hfsplus_uni2asc+0x902/0xa10
> > [  667.124942][ T9805]  kasan_report+0xc6/0x100
> > [  667.124950][ T9805]  ? hfsplus_uni2asc+0x902/0xa10
> > [  667.124959][ T9805]  hfsplus_uni2asc+0x902/0xa10
> > [  667.124966][ T9805]  ? hfsplus_bnode_read+0x14b/0x360
> > [  667.124974][ T9805]  hfsplus_readdir+0x845/0xfc0
> > [  667.124984][ T9805]  ? __pfx_hfsplus_readdir+0x10/0x10
> > [  667.124994][ T9805]  ? stack_trace_save+0x8e/0xc0
> > [  667.125008][ T9805]  ? iterate_dir+0x18b/0xb20
> > [  667.125015][ T9805]  ? trace_lock_acquire+0x85/0xd0
> > [  667.125022][ T9805]  ? lock_acquire+0x30/0x80
> > [  667.125029][ T9805]  ? iterate_dir+0x18b/0xb20
> > [  667.125037][ T9805]  ? down_read_killable+0x1ed/0x4c0
> > [  667.125044][ T9805]  ? putname+0x154/0x1a0
> > [  667.125051][ T9805]  ? __pfx_down_read_killable+0x10/0x10
> > [  667.125058][ T9805]  ? apparmor_file_permission+0x239/0x3e0
> > [  667.125069][ T9805]  iterate_dir+0x296/0xb20
> > [  667.125076][ T9805]  __x64_sys_getdents64+0x13c/0x2c0
> > [  667.125084][ T9805]  ? __pfx___x64_sys_getdents64+0x10/0x10
> > [  667.125091][ T9805]  ? __x64_sys_openat+0x141/0x200
> > [  667.125126][ T9805]  ? __pfx_filldir64+0x10/0x10
> > [  667.125134][ T9805]  ? do_user_addr_fault+0x7fe/0x12f0
> > [  667.125143][ T9805]  do_syscall_64+0xc9/0x480
> > [  667.125151][ T9805]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
> > [  667.125158][ T9805] RIP: 0033:0x7fa8753b2fc9
> > [  667.125164][ T9805] Code: 00 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 48
> > [  667.125172][ T9805] RSP: 002b:00007ffe96f8e0f8 EFLAGS: 00000217
> > ORIG_RAX: 00000000000000d9
> > [  667.125181][ T9805] RAX: ffffffffffffffda RBX: 0000000000000000
> > RCX: 00007fa8753b2fc9
> > [  667.125185][ T9805] RDX: 0000000000000400 RSI: 00002000000063c0
> > RDI: 0000000000000004
> > [  667.125190][ T9805] RBP: 00007ffe96f8e110 R08: 00007ffe96f8e110
> > R09: 00007ffe96f8e110
> > [  667.125195][ T9805] R10: 0000000000000000 R11: 0000000000000217
> > R12: 0000556b1e3b4260
> > [  667.125199][ T9805] R13: 0000000000000000 R14: 0000000000000000
> > R15: 0000000000000000
> > [  667.125207][ T9805]  </TASK>
> > [  667.125210][ T9805]
> > [  667.145632][ T9805] Allocated by task 9805:
> > [  667.145991][ T9805]  kasan_save_stack+0x20/0x40
> > [  667.146352][ T9805]  kasan_save_track+0x14/0x30
> > [  667.146717][ T9805]  __kasan_kmalloc+0xaa/0xb0
> > [  667.147065][ T9805]  __kmalloc_noprof+0x205/0x550
> > [  667.147448][ T9805]  hfsplus_find_init+0x95/0x1f0
> > [  667.147813][ T9805]  hfsplus_readdir+0x220/0xfc0
> > [  667.148174][ T9805]  iterate_dir+0x296/0xb20
> > [  667.148549][ T9805]  __x64_sys_getdents64+0x13c/0x2c0
> > [  667.148937][ T9805]  do_syscall_64+0xc9/0x480
> > [  667.149291][ T9805]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
> > [  667.149809][ T9805]
> > [  667.150030][ T9805] The buggy address belongs to the object at
> > ffff88802592f000
> > [  667.150030][ T9805]  which belongs to the cache kmalloc-2k of
> > size 2048
> > [  667.151282][ T9805] The buggy address is located 0 bytes to the
> > right of
> > [  667.151282][ T9805]  allocated 1036-byte region
> > [ffff88802592f000, ffff88802592f40c)
> > [  667.152580][ T9805]
> > [  667.152798][ T9805] The buggy address belongs to the physical
> > page:
> > [  667.153373][ T9805] page: refcount:0 mapcount:0
> > mapping:0000000000000000 index:0x0 pfn:0x25928
> > [  667.154157][ T9805] head: order:3 mapcount:0 entire_mapcount:0
> > nr_pages_mapped:0 pincount:0
> > [  667.154916][ T9805] anon flags:
> > 0xfff00000000040(head|node=0|zone=1|lastcpupid=0x7ff)
> > [  667.155631][ T9805] page_type: f5(slab)
> > [  667.155997][ T9805] raw: 00fff00000000040 ffff88801b442f00
> > 0000000000000000 dead000000000001
> > [  667.156770][ T9805] raw: 0000000000000000 0000000080080008
> > 00000000f5000000 0000000000000000
> > [  667.157536][ T9805] head: 00fff00000000040 ffff88801b442f00
> > 0000000000000000 dead000000000001
> > [  667.158317][ T9805] head: 0000000000000000 0000000080080008
> > 00000000f5000000 0000000000000000
> > [  667.159088][ T9805] head: 00fff00000000003 ffffea0000964a01
> > 00000000ffffffff 00000000ffffffff
> > [  667.159865][ T9805] head: ffffffffffffffff 0000000000000000
> > 00000000ffffffff 0000000000000008
> > [  667.160643][ T9805] page dumped because: kasan: bad access
> > detected
> > [  667.161216][ T9805] page_owner tracks the page as allocated
> > [  667.161732][ T9805] page last allocated via order 3, migratetype
> > Unmovable, gfp_mask 0xd20c0(__GFP_IO|__GFP_FS|__GFP_NOWARN9
> > [  667.163566][ T9805]  post_alloc_hook+0x1c0/0x230
> > [  667.164003][ T9805]  get_page_from_freelist+0xdeb/0x3b30
> > [  667.164503][ T9805]  __alloc_frozen_pages_noprof+0x25c/0x2460
> > [  667.165040][ T9805]  alloc_pages_mpol+0x1fb/0x550
> > [  667.165489][ T9805]  new_slab+0x23b/0x340
> > [  667.165872][ T9805]  ___slab_alloc+0xd81/0x1960
> > [  667.166313][ T9805]  __slab_alloc.isra.0+0x56/0xb0
> > [  667.166767][ T9805]  __kmalloc_cache_noprof+0x255/0x3e0
> > [  667.167255][ T9805]  psi_cgroup_alloc+0x52/0x2d0
> > [  667.167693][ T9805]  cgroup_mkdir+0x694/0x1210
> > [  667.168118][ T9805]  kernfs_iop_mkdir+0x111/0x190
> > [  667.168568][ T9805]  vfs_mkdir+0x59b/0x8d0
> > [  667.168956][ T9805]  do_mkdirat+0x2ed/0x3d0
> > [  667.169353][ T9805]  __x64_sys_mkdir+0xef/0x140
> > [  667.169784][ T9805]  do_syscall_64+0xc9/0x480
> > [  667.170195][ T9805]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
> > [  667.170730][ T9805] page last free pid 1257 tgid 1257 stack
> > trace:
> > [  667.171304][ T9805]  __free_frozen_pages+0x80c/0x1250
> > [  667.171770][ T9805]  vfree.part.0+0x12b/0xab0
> > [  667.172182][ T9805]  delayed_vfree_work+0x93/0xd0
> > [  667.172612][ T9805]  process_one_work+0x9b5/0x1b80
> > [  667.173067][ T9805]  worker_thread+0x630/0xe60
> > [  667.173486][ T9805]  kthread+0x3a8/0x770
> > [  667.173857][ T9805]  ret_from_fork+0x517/0x6e0
> > [  667.174278][ T9805]  ret_from_fork_asm+0x1a/0x30
> > [  667.174703][ T9805]
> > [  667.174917][ T9805] Memory state around the buggy address:
> > [  667.175411][ T9805]  ffff88802592f300: 00 00 00 00 00 00 00 00
> > 00 00 00 00 00 00 00 00
> > [  667.176114][ T9805]  ffff88802592f380: 00 00 00 00 00 00 00 00
> > 00 00 00 00 00 00 00 00
> > [  667.176830][ T9805] >ffff88802592f400: 00 04 fc fc fc fc fc fc
> > fc fc fc fc fc fc fc fc
> > [  667.177547][ T9805]                       ^
> > [  667.177933][ T9805]  ffff88802592f480: fc fc fc fc fc fc fc fc
> > fc fc fc fc fc fc fc fc
> > [  667.178640][ T9805]  ffff88802592f500: fc fc fc fc fc fc fc fc
> > fc fc fc fc fc fc fc fc
> > [  667.179350][ T9805]
> > ==================================================================
> > 
> > The hfsplus_uni2asc() method operates by struct hfsplus_unistr:
> > 
> > struct hfsplus_unistr {
> > 	__be16 length;
> > 	hfsplus_unichr unicode[HFSPLUS_MAX_STRLEN];
> > } __packed;
> > 
> > where HFSPLUS_MAX_STRLEN is 255 bytes. The issue happens if length
> > of the structure instance has value bigger than 255 (for example,
> > 65283). In such case, pointer on unicode buffer is going beyond of
> > the allocated memory.
> > 
> > The patch fixes the issue by checking the length value of
> > hfsplus_unistr instance and using 255 value in the case if length
> > value is bigger than HFSPLUS_MAX_STRLEN. Potential reason of such
> > situation could be a corruption of Catalog File b-tree's node.
> > 
> > Reported-by: Wenzhi Wang <wenzhi.wang@uwaterloo.ca>
> > Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
> > ---
> >   fs/hfsplus/unicode.c | 4 ++++
> >   1 file changed, 4 insertions(+)
> > 
> > diff --git a/fs/hfsplus/unicode.c b/fs/hfsplus/unicode.c
> > index 73342c925a4b..7e62b3630fcd 100644
> > --- a/fs/hfsplus/unicode.c
> > +++ b/fs/hfsplus/unicode.c
> > @@ -132,7 +132,11 @@ int hfsplus_uni2asc(struct super_block *sb,
> >   
> >   	op = astr;
> >   	ip = ustr->unicode;
> > +
> >   	ustrlen = be16_to_cpu(ustr->length);
> > +	if (ustrlen > HFSPLUS_MAX_STRLEN)
> > +		ustrlen = HFSPLUS_MAX_STRLEN;
> > +
> >   	len = *len_p;
> >   	ce1 = NULL;
> >   	compose = !test_bit(HFSPLUS_SB_NODECOMPOSE,
> > &HFSPLUS_SB(sb)->flags);
> 
> I found that Liu Shixin already sent a similar patch [1].
> 
>  From [2], Long file names for hfsplus is 255 characters.
> 
> Could we mark it as EIO?
> 

The returning of -EIO was my first solution. But if we return -EIO,
then hfsplus_readdir() stop the iteration of names in folder. Even if
we have some issue or corruption, then it makes sense to show all names
in the folder but not to break the names iteration. Probably, we could
add the error message here to warn that something is going wrong here.

Thanks,
Slava.

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

* [PATCH] hfsplus: fix slab-out-of-bounds read in hfsplus_uni2asc()
@ 2025-09-06 10:09 k.chen
  2025-09-06 11:32 ` Greg KH
  2025-09-06 21:37 ` kernel test robot
  0 siblings, 2 replies; 6+ messages in thread
From: k.chen @ 2025-09-06 10:09 UTC (permalink / raw)
  To: security
  Cc: slava, frank.li, linux-fsdevel, glaubitz, wenzhi.wang, liushixin2,
	k.chen

The previous fix (94458781aee6) was insufficient,
as it did not consider that
sizeof(struct hfsplus_attr_unistr) != sizeof(struct hfsplus_unistr).

Fixes: 94458781aee6 ("hfsplus: fix slab-out-of-bounds read in hfsplus_uni2asc()")
Signed-off-by: k.chen <k.chen@smail.nju.edu.cn>
---
 fs/hfsplus/dir.c        | 3 ++-
 fs/hfsplus/hfsplus_fs.h | 2 +-
 fs/hfsplus/unicode.c    | 9 ++++-----
 fs/hfsplus/xattr.c      | 6 ++++--
 4 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c
index 876bbb80fb4d..765627fc5ebe 100644
--- a/fs/hfsplus/dir.c
+++ b/fs/hfsplus/dir.c
@@ -204,7 +204,8 @@ static int hfsplus_readdir(struct file *file, struct dir_context *ctx)
 			fd.entrylength);
 		type = be16_to_cpu(entry.type);
 		len = NLS_MAX_CHARSET_SIZE * HFSPLUS_MAX_STRLEN;
-		err = hfsplus_uni2asc(sb, &fd.key->cat.name, strbuf, &len);
+		err = hfsplus_uni2asc(sb, &fd.key->cat.name, HFSPLUS_MAX_STRLEN,
+				      strbuf, &len);
 		if (err)
 			goto out;
 		if (type == HFSPLUS_FOLDER) {
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
index 96a5c24813dd..49d97c46fd0a 100644
--- a/fs/hfsplus/hfsplus_fs.h
+++ b/fs/hfsplus/hfsplus_fs.h
@@ -522,7 +522,7 @@ int hfsplus_strcasecmp(const struct hfsplus_unistr *s1,
 int hfsplus_strcmp(const struct hfsplus_unistr *s1,
 		   const struct hfsplus_unistr *s2);
 int hfsplus_uni2asc(struct super_block *sb, const struct hfsplus_unistr *ustr,
-		    char *astr, int *len_p);
+		    int max_unistr_len, char *astr, int *len_p);
 int hfsplus_asc2uni(struct super_block *sb, struct hfsplus_unistr *ustr,
 		    int max_unistr_len, const char *astr, int len);
 int hfsplus_hash_dentry(const struct dentry *dentry, struct qstr *str);
diff --git a/fs/hfsplus/unicode.c b/fs/hfsplus/unicode.c
index 36b6cf2a3abb..b4303785ba1e 100644
--- a/fs/hfsplus/unicode.c
+++ b/fs/hfsplus/unicode.c
@@ -119,9 +119,8 @@ static u16 *hfsplus_compose_lookup(u16 *p, u16 cc)
 	return NULL;
 }
 
-int hfsplus_uni2asc(struct super_block *sb,
-		const struct hfsplus_unistr *ustr,
-		char *astr, int *len_p)
+int hfsplus_uni2asc(struct super_block *sb, const struct hfsplus_unistr *ustr,
+		    int max_unistr_len, char *astr, int *len_p)
 {
 	const hfsplus_unichr *ip;
 	struct nls_table *nls = HFSPLUS_SB(sb)->nls;
@@ -134,8 +133,8 @@ int hfsplus_uni2asc(struct super_block *sb,
 	ip = ustr->unicode;
 
 	ustrlen = be16_to_cpu(ustr->length);
-	if (ustrlen > HFSPLUS_MAX_STRLEN) {
-		ustrlen = HFSPLUS_MAX_STRLEN;
+	if (ustrlen > max_unistr_len) {
+		ustrlen = max_unistr_len;
 		pr_err("invalid length %u has been corrected to %d\n",
 			be16_to_cpu(ustr->length), ustrlen);
 	}
diff --git a/fs/hfsplus/xattr.c b/fs/hfsplus/xattr.c
index 18dc3d254d21..9d427cef26f0 100644
--- a/fs/hfsplus/xattr.c
+++ b/fs/hfsplus/xattr.c
@@ -736,8 +736,10 @@ ssize_t hfsplus_listxattr(struct dentry *dentry, char *buffer, size_t size)
 
 		xattr_name_len = NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN;
 		if (hfsplus_uni2asc(inode->i_sb,
-			(const struct hfsplus_unistr *)&fd.key->attr.key_name,
-					strbuf, &xattr_name_len)) {
+				    (const struct hfsplus_attr_unistr *)&fd.key
+					    ->attr.key_name,
+				    HFSPLUS_ATTR_MAX_STRLEN, strbuf,
+				    &xattr_name_len)) {
 			pr_err("unicode conversion failed\n");
 			res = -EIO;
 			goto end_listxattr;
-- 
2.34.1


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

* Re: [PATCH] hfsplus: fix slab-out-of-bounds read in hfsplus_uni2asc()
  2025-09-06 10:09 [PATCH] hfsplus: fix slab-out-of-bounds read in hfsplus_uni2asc() k.chen
@ 2025-09-06 11:32 ` Greg KH
  2025-09-06 21:37 ` kernel test robot
  1 sibling, 0 replies; 6+ messages in thread
From: Greg KH @ 2025-09-06 11:32 UTC (permalink / raw)
  To: k.chen
  Cc: security, slava, frank.li, linux-fsdevel, glaubitz, wenzhi.wang,
	liushixin2

On Sat, Sep 06, 2025 at 06:09:23PM +0800, k.chen wrote:
> The previous fix (94458781aee6) was insufficient,
> as it did not consider that
> sizeof(struct hfsplus_attr_unistr) != sizeof(struct hfsplus_unistr).
> 
> Fixes: 94458781aee6 ("hfsplus: fix slab-out-of-bounds read in hfsplus_uni2asc()")
> Signed-off-by: k.chen <k.chen@smail.nju.edu.cn>

Please use your name and not your email address for the
"signed-off-by:" name portion.

thanks,

greg k-h

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

* Re: [PATCH] hfsplus: fix slab-out-of-bounds read in hfsplus_uni2asc()
  2025-09-06 10:09 [PATCH] hfsplus: fix slab-out-of-bounds read in hfsplus_uni2asc() k.chen
  2025-09-06 11:32 ` Greg KH
@ 2025-09-06 21:37 ` kernel test robot
  1 sibling, 0 replies; 6+ messages in thread
From: kernel test robot @ 2025-09-06 21:37 UTC (permalink / raw)
  To: k.chen
  Cc: llvm, oe-kbuild-all, slava, frank.li, linux-fsdevel, glaubitz,
	wenzhi.wang, liushixin2, k.chen

Hi k.chen,

kernel test robot noticed the following build errors:

[auto build test ERROR on linus/master]
[also build test ERROR on v6.17-rc4 next-20250905]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/k-chen/hfsplus-fix-slab-out-of-bounds-read-in-hfsplus_uni2asc/20250906-181212
base:   linus/master
patch link:    https://lore.kernel.org/r/20250906100923.444243-1-k.chen%40smail.nju.edu.cn
patch subject: [PATCH] hfsplus: fix slab-out-of-bounds read in hfsplus_uni2asc()
config: arm-randconfig-002-20250907 (https://download.01.org/0day-ci/archive/20250907/202509070516.2i61Okso-lkp@intel.com/config)
compiler: clang version 22.0.0git (https://github.com/llvm/llvm-project 7fb1dc08d2f025aad5777bb779dfac1197e9ef87)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250907/202509070516.2i61Okso-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202509070516.2i61Okso-lkp@intel.com/

All errors (new ones prefixed by >>):

>> fs/hfsplus/xattr.c:739:9: error: incompatible pointer types passing 'const struct hfsplus_attr_unistr *' to parameter of type 'const struct hfsplus_unistr *' [-Werror,-Wincompatible-pointer-types]
     739 |                                     (const struct hfsplus_attr_unistr *)&fd.key
         |                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     740 |                                             ->attr.key_name,
         |                                             ~~~~~~~~~~~~~~~
   fs/hfsplus/hfsplus_fs.h:524:74: note: passing argument to parameter 'ustr' here
     524 | int hfsplus_uni2asc(struct super_block *sb, const struct hfsplus_unistr *ustr,
         |                                                                          ^
   1 error generated.


vim +739 fs/hfsplus/xattr.c

   675	
   676	ssize_t hfsplus_listxattr(struct dentry *dentry, char *buffer, size_t size)
   677	{
   678		ssize_t err;
   679		ssize_t res;
   680		struct inode *inode = d_inode(dentry);
   681		struct hfs_find_data fd;
   682		struct hfsplus_attr_key attr_key;
   683		char *strbuf;
   684		int xattr_name_len;
   685	
   686		if ((!S_ISREG(inode->i_mode) &&
   687				!S_ISDIR(inode->i_mode)) ||
   688					HFSPLUS_IS_RSRC(inode))
   689			return -EOPNOTSUPP;
   690	
   691		res = hfsplus_listxattr_finder_info(dentry, buffer, size);
   692		if (res < 0)
   693			return res;
   694		else if (!HFSPLUS_SB(inode->i_sb)->attr_tree)
   695			return (res == 0) ? -EOPNOTSUPP : res;
   696	
   697		err = hfs_find_init(HFSPLUS_SB(inode->i_sb)->attr_tree, &fd);
   698		if (err) {
   699			pr_err("can't init xattr find struct\n");
   700			return err;
   701		}
   702	
   703		strbuf = kzalloc(NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN +
   704				XATTR_MAC_OSX_PREFIX_LEN + 1, GFP_KERNEL);
   705		if (!strbuf) {
   706			res = -ENOMEM;
   707			goto out;
   708		}
   709	
   710		err = hfsplus_find_attr(inode->i_sb, inode->i_ino, NULL, &fd);
   711		if (err) {
   712			if (err == -ENOENT) {
   713				if (res == 0)
   714					res = -ENODATA;
   715				goto end_listxattr;
   716			} else {
   717				res = err;
   718				goto end_listxattr;
   719			}
   720		}
   721	
   722		for (;;) {
   723			u16 key_len = hfs_bnode_read_u16(fd.bnode, fd.keyoffset);
   724	
   725			if (key_len == 0 || key_len > fd.tree->max_key_len) {
   726				pr_err("invalid xattr key length: %d\n", key_len);
   727				res = -EIO;
   728				goto end_listxattr;
   729			}
   730	
   731			hfs_bnode_read(fd.bnode, &attr_key,
   732					fd.keyoffset, key_len + sizeof(key_len));
   733	
   734			if (be32_to_cpu(attr_key.cnid) != inode->i_ino)
   735				goto end_listxattr;
   736	
   737			xattr_name_len = NLS_MAX_CHARSET_SIZE * HFSPLUS_ATTR_MAX_STRLEN;
   738			if (hfsplus_uni2asc(inode->i_sb,
 > 739					    (const struct hfsplus_attr_unistr *)&fd.key
   740						    ->attr.key_name,
   741					    HFSPLUS_ATTR_MAX_STRLEN, strbuf,
   742					    &xattr_name_len)) {
   743				pr_err("unicode conversion failed\n");
   744				res = -EIO;
   745				goto end_listxattr;
   746			}
   747	
   748			if (!buffer || !size) {
   749				if (can_list(strbuf))
   750					res += name_len(strbuf, xattr_name_len);
   751			} else if (can_list(strbuf)) {
   752				if (size < (res + name_len(strbuf, xattr_name_len))) {
   753					res = -ERANGE;
   754					goto end_listxattr;
   755				} else
   756					res += copy_name(buffer + res,
   757							strbuf, xattr_name_len);
   758			}
   759	
   760			if (hfs_brec_goto(&fd, 1))
   761				goto end_listxattr;
   762		}
   763	
   764	end_listxattr:
   765		kfree(strbuf);
   766	out:
   767		hfs_find_exit(&fd);
   768		return res;
   769	}
   770	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

end of thread, other threads:[~2025-09-06 21:38 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-06 10:09 [PATCH] hfsplus: fix slab-out-of-bounds read in hfsplus_uni2asc() k.chen
2025-09-06 11:32 ` Greg KH
2025-09-06 21:37 ` kernel test robot
  -- strict thread matches above, loose matches on Subject: below --
2025-07-03 18:41 Viacheslav Dubeyko
2025-07-09  5:10 ` Yangtao Li
2025-07-09 18:19   ` Viacheslav Dubeyko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).