hfs_find_init() sizes the per-tree key buffers from max_key_len: ptr = kzalloc(tree->max_key_len * 2 + 4, GFP_KERNEL); which is 24 bytes for the extents tree (max_key_len 10) and 1036 for the catalog tree. hfs_bnode_read_key() however bounds both the copy and the reject-path memset against the generic key union: if (key_len > sizeof(hfsplus_btree_key) || key_len < 1) { memset(key, 0, sizeof(hfsplus_btree_key)); pr_err("hfsplus: Invalid key length: %u\n", key_len); return; } hfs_bnode_read(node, key, off, key_len); sizeof(hfsplus_btree_key) is 518 (the catalog key size; the union of cat/ext/attr keys). For the extents tree the bound is larger than the 24-byte buffer it protects, so the check is inert there: an on-disk key length between 10 and 516 passes it and the memcpy overflows the allocation, and a "rejected" key length takes the memset path, which writes 518 bytes into the same 24-byte allocation. Both paths were observed as KASAN slab-out-of-bounds writes on the writeback path of a crafted image: BUG: KASAN: slab-out-of-bounds in hfsplus_bnode_read+0x30/0x5f0 Write of size 502 at addr ... by task init/1 hfsplus_bnode_read -> hfs_bnode_read_key hfs_brec_insert -> __hfsplus_ext_write_extent hfsplus_ext_write_extent -> hfsplus_write_inode -> hfsplus_file_fsync allocated 24-byte region (kmalloc-32) by hfsplus_find_init Bound both the copy and the memset against the actual buffer size, tree->max_key_len + 2, which is the natural limit for every tree (the extents tree can never see a key above HFSPLUS_EXT_KEYLEN on a well-formed volume; the catalog and attribute trees already allocate buffers that cover their full key sizes). Tested with the reproducer from the bug report: the extents-tree image that previously wrote 502 bytes into the 24-byte allocation now fails the bound and logs "Invalid key length"; the negative control (NUL-terminated short key) still parses and writes normally. Reported-by: Guikun Yang Signed-off-by: Guikun Yang --- diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index 3a1a1fa6f..0774b945c 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -84,8 +84,8 @@ void hfs_bnode_read_key(struct hfs_bnode *node, void *key, u32 off) else key_len = tree->max_key_len + 2; - if (key_len > sizeof(hfsplus_btree_key) || key_len < 1) { - memset(key, 0, sizeof(hfsplus_btree_key)); + if (key_len > tree->max_key_len + 2 || key_len < 1) { + memset(key, 0, tree->max_key_len + 2); pr_err("hfsplus: Invalid key length: %u\n", key_len); return; }