Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

hfs/hfsplus: prevent getting negative values of offset/length

The syzbot reported KASAN out-of-bounds issue in
hfs_bnode_move():

[ 45.588165][ T9821] hfs: dst 14, src 65536, len -65536
[ 45.588895][ T9821] ==================================================================
[ 45.590114][ T9821] BUG: KASAN: out-of-bounds in hfs_bnode_move+0xfd/0x140
[ 45.591127][ T9821] Read of size 18446744073709486080 at addr ffff888035935400 by task repro/9821
[ 45.592207][ T9821]
[ 45.592420][ T9821] CPU: 0 UID: 0 PID: 9821 Comm: repro Not tainted 6.16.0-rc7-dirty #42 PREEMPT(full)
[ 45.592428][ T9821] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[ 45.592431][ T9821] Call Trace:
[ 45.592434][ T9821] <TASK>
[ 45.592437][ T9821] dump_stack_lvl+0x1c1/0x2a0
[ 45.592446][ T9821] ? __virt_addr_valid+0x1c8/0x5c0
[ 45.592454][ T9821] ? __pfx_dump_stack_lvl+0x10/0x10
[ 45.592461][ T9821] ? rcu_is_watching+0x15/0xb0
[ 45.592469][ T9821] ? lock_release+0x4b/0x3e0
[ 45.592476][ T9821] ? __virt_addr_valid+0x1c8/0x5c0
[ 45.592483][ T9821] ? __virt_addr_valid+0x4a5/0x5c0
[ 45.592491][ T9821] print_report+0x17e/0x7c0
[ 45.592497][ T9821] ? __virt_addr_valid+0x1c8/0x5c0
[ 45.592504][ T9821] ? __virt_addr_valid+0x4a5/0x5c0
[ 45.592511][ T9821] ? __phys_addr+0xd3/0x180
[ 45.592519][ T9821] ? hfs_bnode_move+0xfd/0x140
[ 45.592526][ T9821] kasan_report+0x147/0x180
[ 45.592531][ T9821] ? _printk+0xcf/0x120
[ 45.592537][ T9821] ? hfs_bnode_move+0xfd/0x140
[ 45.592544][ T9821] ? hfs_bnode_move+0xfd/0x140
[ 45.592552][ T9821] kasan_check_range+0x2b0/0x2c0
[ 45.592557][ T9821] ? hfs_bnode_move+0xfd/0x140
[ 45.592565][ T9821] __asan_memmove+0x29/0x70
[ 45.592572][ T9821] hfs_bnode_move+0xfd/0x140
[ 45.592580][ T9821] hfs_brec_remove+0x473/0x560
[ 45.592589][ T9821] hfs_cat_move+0x6fb/0x960
[ 45.592598][ T9821] ? __pfx_hfs_cat_move+0x10/0x10
[ 45.592607][ T9821] ? seqcount_lockdep_reader_access+0x122/0x1c0
[ 45.592614][ T9821] ? lockdep_hardirqs_on+0x9c/0x150
[ 45.592631][ T9821] ? __lock_acquire+0xaec/0xd80
[ 45.592641][ T9821] hfs_rename+0x1dc/0x2d0
[ 45.592649][ T9821] ? __pfx_hfs_rename+0x10/0x10
[ 45.592657][ T9821] vfs_rename+0xac6/0xed0
[ 45.592664][ T9821] ? __pfx_vfs_rename+0x10/0x10
[ 45.592670][ T9821] ? d_alloc+0x144/0x190
[ 45.592677][ T9821] ? bpf_lsm_path_rename+0x9/0x20
[ 45.592683][ T9821] ? security_path_rename+0x17d/0x490
[ 45.592691][ T9821] do_renameat2+0x890/0xc50
[ 45.592699][ T9821] ? __pfx_do_renameat2+0x10/0x10
[ 45.592707][ T9821] ? getname_flags+0x1e5/0x540
[ 45.592714][ T9821] __x64_sys_rename+0x82/0x90
[ 45.592720][ T9821] ? entry_SYSCALL_64_after_hwframe+0x77/0x7f
[ 45.592725][ T9821] do_syscall_64+0xf3/0x3a0
[ 45.592741][ T9821] ? exc_page_fault+0x9f/0xf0
[ 45.592748][ T9821] entry_SYSCALL_64_after_hwframe+0x77/0x7f
[ 45.592754][ T9821] RIP: 0033:0x7f7f73fe3fc9
[ 45.592760][ T9821] 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
[ 45.592765][ T9821] RSP: 002b:00007ffc7e116cf8 EFLAGS: 00000283 ORIG_RAX: 0000000000000052
[ 45.592772][ T9821] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f7f73fe3fc9
[ 45.592776][ T9821] RDX: 0000200000000871 RSI: 0000200000000780 RDI: 00002000000003c0
[ 45.592781][ T9821] RBP: 00007ffc7e116d00 R08: 0000000000000000 R09: 00007ffc7e116d30
[ 45.592784][ T9821] R10: fffffffffffffff0 R11: 0000000000000283 R12: 00005557e81f8250
[ 45.592788][ T9821] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
[ 45.592795][ T9821] </TASK>
[ 45.592797][ T9821]
[ 45.619721][ T9821] The buggy address belongs to the physical page:
[ 45.620300][ T9821] page: refcount:1 mapcount:1 mapping:0000000000000000 index:0x559a88174 pfn:0x35935
[ 45.621150][ T9821] memcg:ffff88810a1d5b00
[ 45.621531][ T9821] anon flags: 0xfff60000020838(uptodate|dirty|lru|owner_2|swapbacked|node=0|zone=1|lastcpupid=0x7ff)
[ 45.622496][ T9821] raw: 00fff60000020838 ffffea0000d64d88 ffff888021753e10 ffff888029da0771
[ 45.623260][ T9821] raw: 0000000559a88174 0000000000000000 0000000100000000 ffff88810a1d5b00
[ 45.624030][ T9821] page dumped because: kasan: bad access detected
[ 45.624602][ T9821] page_owner tracks the page as allocated
[ 45.625115][ T9821] page last allocated via order 0, migratetype Movable, gfp_mask 0x140dca(GFP_HIGHUSER_MOVABLE|__GFP_ZERO0
[ 45.626685][ T9821] post_alloc_hook+0x240/0x2a0
[ 45.627127][ T9821] get_page_from_freelist+0x2101/0x21e0
[ 45.627628][ T9821] __alloc_frozen_pages_noprof+0x274/0x380
[ 45.628154][ T9821] alloc_pages_mpol+0x241/0x4b0
[ 45.628593][ T9821] vma_alloc_folio_noprof+0xe4/0x210
[ 45.629066][ T9821] folio_prealloc+0x30/0x180
[ 45.629487][ T9821] __handle_mm_fault+0x34bd/0x5640
[ 45.629957][ T9821] handle_mm_fault+0x40e/0x8e0
[ 45.630392][ T9821] do_user_addr_fault+0xa81/0x1390
[ 45.630862][ T9821] exc_page_fault+0x76/0xf0
[ 45.631273][ T9821] asm_exc_page_fault+0x26/0x30
[ 45.631712][ T9821] page last free pid 5269 tgid 5269 stack trace:
[ 45.632281][ T9821] free_unref_folios+0xc73/0x14c0
[ 45.632740][ T9821] folios_put_refs+0x55b/0x640
[ 45.633177][ T9821] free_pages_and_swap_cache+0x26d/0x510
[ 45.633685][ T9821] tlb_flush_mmu+0x3a0/0x680
[ 45.634105][ T9821] tlb_finish_mmu+0xd4/0x200
[ 45.634525][ T9821] exit_mmap+0x44c/0xb70
[ 45.634914][ T9821] __mmput+0x118/0x420
[ 45.635286][ T9821] exit_mm+0x1da/0x2c0
[ 45.635659][ T9821] do_exit+0x652/0x2330
[ 45.636039][ T9821] do_group_exit+0x21c/0x2d0
[ 45.636457][ T9821] __x64_sys_exit_group+0x3f/0x40
[ 45.636915][ T9821] x64_sys_call+0x21ba/0x21c0
[ 45.637342][ T9821] do_syscall_64+0xf3/0x3a0
[ 45.637756][ T9821] entry_SYSCALL_64_after_hwframe+0x77/0x7f
[ 45.638290][ T9821] page has been migrated, last migrate reason: numa_misplaced
[ 45.638956][ T9821]
[ 45.639173][ T9821] Memory state around the buggy address:
[ 45.639677][ T9821] ffff888035935300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 45.640397][ T9821] ffff888035935380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 45.641117][ T9821] >ffff888035935400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 45.641837][ T9821] ^
[ 45.642207][ T9821] ffff888035935480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 45.642929][ T9821] ffff888035935500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 45.643650][ T9821] ==================================================================

This commit [1] fixes the issue if an offset inside of b-tree node
or length of the request is bigger than b-tree node. However,
this fix is still not ready for negative values
of the offset or length. Moreover, negative values of
the offset or length doesn't make sense for b-tree's
operations. Because we could try to access the memory address
outside of the beginning of memory page's addresses range.
Also, using of negative values make logic very complicated,
unpredictable, and we could access the wrong item(s)
in the b-tree node.

This patch changes b-tree interface by means of converting
signed integer arguments of offset and length on u32 type.
Such conversion has goal to prevent of using negative values
unintentionally or by mistake in b-tree operations.

[1] 'commit a431930c9bac ("hfs: fix slab-out-of-bounds in hfs_bnode_read()")'

Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
cc: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
cc: Yangtao Li <frank.li@vivo.com>
cc: linux-fsdevel@vger.kernel.org
Link: https://lore.kernel.org/r/20251002200020.2578311-1-slava@dubeyko.com
Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>

+171 -153
+1 -1
fs/hfs/bfind.c
··· 167 167 return res; 168 168 } 169 169 170 - int hfs_brec_read(struct hfs_find_data *fd, void *rec, int rec_len) 170 + int hfs_brec_read(struct hfs_find_data *fd, void *rec, u32 rec_len) 171 171 { 172 172 int res; 173 173
+26 -26
fs/hfs/bnode.c
··· 16 16 #include "btree.h" 17 17 18 18 static inline 19 - bool is_bnode_offset_valid(struct hfs_bnode *node, int off) 19 + bool is_bnode_offset_valid(struct hfs_bnode *node, u32 off) 20 20 { 21 21 bool is_valid = off < node->tree->node_size; 22 22 23 23 if (!is_valid) { 24 24 pr_err("requested invalid offset: " 25 25 "NODE: id %u, type %#x, height %u, " 26 - "node_size %u, offset %d\n", 26 + "node_size %u, offset %u\n", 27 27 node->this, node->type, node->height, 28 28 node->tree->node_size, off); 29 29 } ··· 32 32 } 33 33 34 34 static inline 35 - int check_and_correct_requested_length(struct hfs_bnode *node, int off, int len) 35 + u32 check_and_correct_requested_length(struct hfs_bnode *node, u32 off, u32 len) 36 36 { 37 37 unsigned int node_size; 38 38 ··· 42 42 node_size = node->tree->node_size; 43 43 44 44 if ((off + len) > node_size) { 45 - int new_len = (int)node_size - off; 45 + u32 new_len = node_size - off; 46 46 47 47 pr_err("requested length has been corrected: " 48 48 "NODE: id %u, type %#x, height %u, " 49 - "node_size %u, offset %d, " 50 - "requested_len %d, corrected_len %d\n", 49 + "node_size %u, offset %u, " 50 + "requested_len %u, corrected_len %u\n", 51 51 node->this, node->type, node->height, 52 52 node->tree->node_size, off, len, new_len); 53 53 ··· 57 57 return len; 58 58 } 59 59 60 - void hfs_bnode_read(struct hfs_bnode *node, void *buf, int off, int len) 60 + void hfs_bnode_read(struct hfs_bnode *node, void *buf, u32 off, u32 len) 61 61 { 62 62 struct page *page; 63 - int pagenum; 64 - int bytes_read; 65 - int bytes_to_read; 63 + u32 pagenum; 64 + u32 bytes_read; 65 + u32 bytes_to_read; 66 66 67 67 if (!is_bnode_offset_valid(node, off)) 68 68 return; ··· 70 70 if (len == 0) { 71 71 pr_err("requested zero length: " 72 72 "NODE: id %u, type %#x, height %u, " 73 - "node_size %u, offset %d, len %d\n", 73 + "node_size %u, offset %u, len %u\n", 74 74 node->this, node->type, node->height, 75 75 node->tree->node_size, off, len); 76 76 return; ··· 86 86 if (pagenum >= node->tree->pages_per_bnode) 87 87 break; 88 88 page = node->page[pagenum]; 89 - bytes_to_read = min_t(int, len - bytes_read, PAGE_SIZE - off); 89 + bytes_to_read = min_t(u32, len - bytes_read, PAGE_SIZE - off); 90 90 91 91 memcpy_from_page(buf + bytes_read, page, off, bytes_to_read); 92 92 ··· 95 95 } 96 96 } 97 97 98 - u16 hfs_bnode_read_u16(struct hfs_bnode *node, int off) 98 + u16 hfs_bnode_read_u16(struct hfs_bnode *node, u32 off) 99 99 { 100 100 __be16 data; 101 101 // optimize later... ··· 103 103 return be16_to_cpu(data); 104 104 } 105 105 106 - u8 hfs_bnode_read_u8(struct hfs_bnode *node, int off) 106 + u8 hfs_bnode_read_u8(struct hfs_bnode *node, u32 off) 107 107 { 108 108 u8 data; 109 109 // optimize later... ··· 111 111 return data; 112 112 } 113 113 114 - void hfs_bnode_read_key(struct hfs_bnode *node, void *key, int off) 114 + void hfs_bnode_read_key(struct hfs_bnode *node, void *key, u32 off) 115 115 { 116 116 struct hfs_btree *tree; 117 - int key_len; 117 + u32 key_len; 118 118 119 119 tree = node->tree; 120 120 if (node->type == HFS_NODE_LEAF || ··· 125 125 126 126 if (key_len > sizeof(hfs_btree_key) || key_len < 1) { 127 127 memset(key, 0, sizeof(hfs_btree_key)); 128 - pr_err("hfs: Invalid key length: %d\n", key_len); 128 + pr_err("hfs: Invalid key length: %u\n", key_len); 129 129 return; 130 130 } 131 131 132 132 hfs_bnode_read(node, key, off, key_len); 133 133 } 134 134 135 - void hfs_bnode_write(struct hfs_bnode *node, void *buf, int off, int len) 135 + void hfs_bnode_write(struct hfs_bnode *node, void *buf, u32 off, u32 len) 136 136 { 137 137 struct page *page; 138 138 ··· 142 142 if (len == 0) { 143 143 pr_err("requested zero length: " 144 144 "NODE: id %u, type %#x, height %u, " 145 - "node_size %u, offset %d, len %d\n", 145 + "node_size %u, offset %u, len %u\n", 146 146 node->this, node->type, node->height, 147 147 node->tree->node_size, off, len); 148 148 return; ··· 157 157 set_page_dirty(page); 158 158 } 159 159 160 - void hfs_bnode_write_u16(struct hfs_bnode *node, int off, u16 data) 160 + void hfs_bnode_write_u16(struct hfs_bnode *node, u32 off, u16 data) 161 161 { 162 162 __be16 v = cpu_to_be16(data); 163 163 // optimize later... 164 164 hfs_bnode_write(node, &v, off, 2); 165 165 } 166 166 167 - void hfs_bnode_write_u8(struct hfs_bnode *node, int off, u8 data) 167 + void hfs_bnode_write_u8(struct hfs_bnode *node, u32 off, u8 data) 168 168 { 169 169 // optimize later... 170 170 hfs_bnode_write(node, &data, off, 1); 171 171 } 172 172 173 - void hfs_bnode_clear(struct hfs_bnode *node, int off, int len) 173 + void hfs_bnode_clear(struct hfs_bnode *node, u32 off, u32 len) 174 174 { 175 175 struct page *page; 176 176 ··· 180 180 if (len == 0) { 181 181 pr_err("requested zero length: " 182 182 "NODE: id %u, type %#x, height %u, " 183 - "node_size %u, offset %d, len %d\n", 183 + "node_size %u, offset %u, len %u\n", 184 184 node->this, node->type, node->height, 185 185 node->tree->node_size, off, len); 186 186 return; ··· 195 195 set_page_dirty(page); 196 196 } 197 197 198 - void hfs_bnode_copy(struct hfs_bnode *dst_node, int dst, 199 - struct hfs_bnode *src_node, int src, int len) 198 + void hfs_bnode_copy(struct hfs_bnode *dst_node, u32 dst, 199 + struct hfs_bnode *src_node, u32 src, u32 len) 200 200 { 201 201 struct page *src_page, *dst_page; 202 202 ··· 216 216 set_page_dirty(dst_page); 217 217 } 218 218 219 - void hfs_bnode_move(struct hfs_bnode *node, int dst, int src, int len) 219 + void hfs_bnode_move(struct hfs_bnode *node, u32 dst, u32 src, u32 len) 220 220 { 221 221 struct page *page; 222 222 void *ptr;
+1 -1
fs/hfs/brec.c
··· 62 62 return retval; 63 63 } 64 64 65 - int hfs_brec_insert(struct hfs_find_data *fd, void *entry, int entry_len) 65 + int hfs_brec_insert(struct hfs_find_data *fd, void *entry, u32 entry_len) 66 66 { 67 67 struct hfs_btree *tree; 68 68 struct hfs_bnode *node, *new_node;
+1 -1
fs/hfs/btree.c
··· 259 259 } 260 260 261 261 /* Make sure @tree has enough space for the @rsvd_nodes */ 262 - int hfs_bmap_reserve(struct hfs_btree *tree, int rsvd_nodes) 262 + int hfs_bmap_reserve(struct hfs_btree *tree, u32 rsvd_nodes) 263 263 { 264 264 struct inode *inode = tree->inode; 265 265 u32 count;
+36 -35
fs/hfs/btree.h
··· 86 86 87 87 88 88 /* btree.c */ 89 - extern struct hfs_btree *hfs_btree_open(struct super_block *, u32, btree_keycmp); 90 - extern void hfs_btree_close(struct hfs_btree *); 91 - extern void hfs_btree_write(struct hfs_btree *); 92 - extern int hfs_bmap_reserve(struct hfs_btree *, int); 93 - extern struct hfs_bnode * hfs_bmap_alloc(struct hfs_btree *); 89 + extern struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, 90 + btree_keycmp keycmp); 91 + extern void hfs_btree_close(struct hfs_btree *tree); 92 + extern void hfs_btree_write(struct hfs_btree *tree); 93 + extern int hfs_bmap_reserve(struct hfs_btree *tree, u32 rsvd_nodes); 94 + extern struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree); 94 95 extern void hfs_bmap_free(struct hfs_bnode *node); 95 96 96 97 /* bnode.c */ 97 - extern void hfs_bnode_read(struct hfs_bnode *, void *, int, int); 98 - extern u16 hfs_bnode_read_u16(struct hfs_bnode *, int); 99 - extern u8 hfs_bnode_read_u8(struct hfs_bnode *, int); 100 - extern void hfs_bnode_read_key(struct hfs_bnode *, void *, int); 101 - extern void hfs_bnode_write(struct hfs_bnode *, void *, int, int); 102 - extern void hfs_bnode_write_u16(struct hfs_bnode *, int, u16); 103 - extern void hfs_bnode_write_u8(struct hfs_bnode *, int, u8); 104 - extern void hfs_bnode_clear(struct hfs_bnode *, int, int); 105 - extern void hfs_bnode_copy(struct hfs_bnode *, int, 106 - struct hfs_bnode *, int, int); 107 - extern void hfs_bnode_move(struct hfs_bnode *, int, int, int); 108 - extern void hfs_bnode_dump(struct hfs_bnode *); 109 - extern void hfs_bnode_unlink(struct hfs_bnode *); 110 - extern struct hfs_bnode *hfs_bnode_findhash(struct hfs_btree *, u32); 111 - extern struct hfs_bnode *hfs_bnode_find(struct hfs_btree *, u32); 112 - extern void hfs_bnode_unhash(struct hfs_bnode *); 113 - extern void hfs_bnode_free(struct hfs_bnode *); 114 - extern struct hfs_bnode *hfs_bnode_create(struct hfs_btree *, u32); 115 - extern void hfs_bnode_get(struct hfs_bnode *); 116 - extern void hfs_bnode_put(struct hfs_bnode *); 98 + extern void hfs_bnode_read(struct hfs_bnode *node, void *buf, u32 off, u32 len); 99 + extern u16 hfs_bnode_read_u16(struct hfs_bnode *node, u32 off); 100 + extern u8 hfs_bnode_read_u8(struct hfs_bnode *node, u32 off); 101 + extern void hfs_bnode_read_key(struct hfs_bnode *node, void *key, u32 off); 102 + extern void hfs_bnode_write(struct hfs_bnode *node, void *buf, u32 off, u32 len); 103 + extern void hfs_bnode_write_u16(struct hfs_bnode *node, u32 off, u16 data); 104 + extern void hfs_bnode_write_u8(struct hfs_bnode *node, u32 off, u8 data); 105 + extern void hfs_bnode_clear(struct hfs_bnode *node, u32 off, u32 len); 106 + extern void hfs_bnode_copy(struct hfs_bnode *dst_node, u32 dst, 107 + struct hfs_bnode *src_node, u32 src, u32 len); 108 + extern void hfs_bnode_move(struct hfs_bnode *node, u32 dst, u32 src, u32 len); 109 + extern void hfs_bnode_dump(struct hfs_bnode *node); 110 + extern void hfs_bnode_unlink(struct hfs_bnode *node); 111 + extern struct hfs_bnode *hfs_bnode_findhash(struct hfs_btree *tree, u32 cnid); 112 + extern struct hfs_bnode *hfs_bnode_find(struct hfs_btree *tree, u32 num); 113 + extern void hfs_bnode_unhash(struct hfs_bnode *node); 114 + extern void hfs_bnode_free(struct hfs_bnode *node); 115 + extern struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num); 116 + extern void hfs_bnode_get(struct hfs_bnode *node); 117 + extern void hfs_bnode_put(struct hfs_bnode *node); 117 118 118 119 /* brec.c */ 119 - extern u16 hfs_brec_lenoff(struct hfs_bnode *, u16, u16 *); 120 - extern u16 hfs_brec_keylen(struct hfs_bnode *, u16); 121 - extern int hfs_brec_insert(struct hfs_find_data *, void *, int); 122 - extern int hfs_brec_remove(struct hfs_find_data *); 120 + extern u16 hfs_brec_lenoff(struct hfs_bnode *node, u16 rec, u16 *off); 121 + extern u16 hfs_brec_keylen(struct hfs_bnode *node, u16 rec); 122 + extern int hfs_brec_insert(struct hfs_find_data *fd, void *entry, u32 entry_len); 123 + extern int hfs_brec_remove(struct hfs_find_data *fd); 123 124 124 125 /* bfind.c */ 125 - extern int hfs_find_init(struct hfs_btree *, struct hfs_find_data *); 126 - extern void hfs_find_exit(struct hfs_find_data *); 127 - extern int __hfs_brec_find(struct hfs_bnode *, struct hfs_find_data *); 128 - extern int hfs_brec_find(struct hfs_find_data *); 129 - extern int hfs_brec_read(struct hfs_find_data *, void *, int); 130 - extern int hfs_brec_goto(struct hfs_find_data *, int); 126 + extern int hfs_find_init(struct hfs_btree *tree, struct hfs_find_data *fd); 127 + extern void hfs_find_exit(struct hfs_find_data *fd); 128 + extern int __hfs_brec_find(struct hfs_bnode *bnode, struct hfs_find_data *fd); 129 + extern int hfs_brec_find(struct hfs_find_data *fd); 130 + extern int hfs_brec_read(struct hfs_find_data *fd, void *rec, u32 rec_len); 131 + extern int hfs_brec_goto(struct hfs_find_data *fd, int cnt); 131 132 132 133 133 134 struct hfs_bnode_desc {
+52 -36
fs/hfs/hfs_fs.h
··· 140 140 #define HFS_FLG_ALT_MDB_DIRTY 2 141 141 142 142 /* bitmap.c */ 143 - extern u32 hfs_vbm_search_free(struct super_block *, u32, u32 *); 144 - extern int hfs_clear_vbm_bits(struct super_block *, u16, u16); 143 + extern u32 hfs_vbm_search_free(struct super_block *sb, u32 goal, u32 *num_bits); 144 + extern int hfs_clear_vbm_bits(struct super_block *sb, u16 start, u16 count); 145 145 146 146 /* catalog.c */ 147 - extern int hfs_cat_keycmp(const btree_key *, const btree_key *); 147 + extern int hfs_cat_keycmp(const btree_key *key1, const btree_key *key2); 148 148 struct hfs_find_data; 149 - extern int hfs_cat_find_brec(struct super_block *, u32, struct hfs_find_data *); 150 - extern int hfs_cat_create(u32, struct inode *, const struct qstr *, struct inode *); 151 - extern int hfs_cat_delete(u32, struct inode *, const struct qstr *); 152 - extern int hfs_cat_move(u32, struct inode *, const struct qstr *, 153 - struct inode *, const struct qstr *); 154 - extern void hfs_cat_build_key(struct super_block *, btree_key *, u32, const struct qstr *); 149 + extern int hfs_cat_find_brec(struct super_block *sb, u32 cnid, 150 + struct hfs_find_data *fd); 151 + extern int hfs_cat_create(u32 cnid, struct inode *dir, 152 + const struct qstr *str, struct inode *inode); 153 + extern int hfs_cat_delete(u32 cnid, struct inode *dir, const struct qstr *str); 154 + extern int hfs_cat_move(u32 cnid, struct inode *src_dir, 155 + const struct qstr *src_name, 156 + struct inode *dst_dir, 157 + const struct qstr *dst_name); 158 + extern void hfs_cat_build_key(struct super_block *sb, btree_key *key, 159 + u32 parent, const struct qstr *name); 155 160 156 161 /* dir.c */ 157 162 extern const struct file_operations hfs_dir_operations; 158 163 extern const struct inode_operations hfs_dir_inode_operations; 159 164 160 165 /* extent.c */ 161 - extern int hfs_ext_keycmp(const btree_key *, const btree_key *); 166 + extern int hfs_ext_keycmp(const btree_key *key1, const btree_key *key2); 162 167 extern u16 hfs_ext_find_block(struct hfs_extent *ext, u16 off); 163 - extern int hfs_free_fork(struct super_block *, struct hfs_cat_file *, int); 164 - extern int hfs_ext_write_extent(struct inode *); 165 - extern int hfs_extend_file(struct inode *); 166 - extern void hfs_file_truncate(struct inode *); 168 + extern int hfs_free_fork(struct super_block *sb, 169 + struct hfs_cat_file *file, int type); 170 + extern int hfs_ext_write_extent(struct inode *inode); 171 + extern int hfs_extend_file(struct inode *inode); 172 + extern void hfs_file_truncate(struct inode *inode); 167 173 168 - extern int hfs_get_block(struct inode *, sector_t, struct buffer_head *, int); 174 + extern int hfs_get_block(struct inode *inode, sector_t block, 175 + struct buffer_head *bh_result, int create); 169 176 170 177 /* inode.c */ 171 178 extern const struct address_space_operations hfs_aops; 172 179 extern const struct address_space_operations hfs_btree_aops; 173 180 174 181 int hfs_write_begin(const struct kiocb *iocb, struct address_space *mapping, 175 - loff_t pos, unsigned len, struct folio **foliop, void **fsdata); 176 - extern struct inode *hfs_new_inode(struct inode *, const struct qstr *, umode_t); 177 - extern void hfs_inode_write_fork(struct inode *, struct hfs_extent *, __be32 *, __be32 *); 178 - extern int hfs_write_inode(struct inode *, struct writeback_control *); 179 - extern int hfs_inode_setattr(struct mnt_idmap *, struct dentry *, 180 - struct iattr *); 182 + loff_t pos, unsigned int len, struct folio **foliop, 183 + void **fsdata); 184 + extern struct inode *hfs_new_inode(struct inode *dir, const struct qstr *name, 185 + umode_t mode); 186 + extern void hfs_inode_write_fork(struct inode *inode, struct hfs_extent *ext, 187 + __be32 *log_size, __be32 *phys_size); 188 + extern int hfs_write_inode(struct inode *inode, struct writeback_control *wbc); 189 + extern int hfs_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry, 190 + struct iattr *attr); 181 191 extern void hfs_inode_read_fork(struct inode *inode, struct hfs_extent *ext, 182 - __be32 log_size, __be32 phys_size, u32 clump_size); 183 - extern struct inode *hfs_iget(struct super_block *, struct hfs_cat_key *, hfs_cat_rec *); 184 - extern void hfs_evict_inode(struct inode *); 185 - extern void hfs_delete_inode(struct inode *); 192 + __be32 __log_size, __be32 phys_size, 193 + u32 clump_size); 194 + extern struct inode *hfs_iget(struct super_block *sb, struct hfs_cat_key *key, 195 + hfs_cat_rec *rec); 196 + extern void hfs_evict_inode(struct inode *inode); 197 + extern void hfs_delete_inode(struct inode *inode); 186 198 187 199 /* attr.c */ 188 200 extern const struct xattr_handler * const hfs_xattr_handlers[]; 189 201 190 202 /* mdb.c */ 191 - extern int hfs_mdb_get(struct super_block *); 192 - extern void hfs_mdb_commit(struct super_block *); 193 - extern void hfs_mdb_close(struct super_block *); 194 - extern void hfs_mdb_put(struct super_block *); 203 + extern int hfs_mdb_get(struct super_block *sb); 204 + extern void hfs_mdb_commit(struct super_block *sb); 205 + extern void hfs_mdb_close(struct super_block *sb); 206 + extern void hfs_mdb_put(struct super_block *sb); 195 207 196 208 /* part_tbl.c */ 197 - extern int hfs_part_find(struct super_block *, sector_t *, sector_t *); 209 + extern int hfs_part_find(struct super_block *sb, 210 + sector_t *part_start, sector_t *part_size); 198 211 199 212 /* string.c */ 200 213 extern const struct dentry_operations hfs_dentry_operations; 201 214 202 - extern int hfs_hash_dentry(const struct dentry *, struct qstr *); 203 - extern int hfs_strcmp(const unsigned char *, unsigned int, 204 - const unsigned char *, unsigned int); 215 + extern int hfs_hash_dentry(const struct dentry *dentry, struct qstr *this); 216 + extern int hfs_strcmp(const unsigned char *s1, unsigned int len1, 217 + const unsigned char *s2, unsigned int len2); 205 218 extern int hfs_compare_dentry(const struct dentry *dentry, 206 - unsigned int len, const char *str, const struct qstr *name); 219 + unsigned int len, const char *str, 220 + const struct qstr *name); 207 221 208 222 /* trans.c */ 209 - extern void hfs_asc2mac(struct super_block *, struct hfs_name *, const struct qstr *); 210 - extern int hfs_mac2asc(struct super_block *, char *, const struct hfs_name *); 223 + extern void hfs_asc2mac(struct super_block *sb, 224 + struct hfs_name *out, const struct qstr *in); 225 + extern int hfs_mac2asc(struct super_block *sb, 226 + char *out, const struct hfs_name *in); 211 227 212 228 /* super.c */ 213 229 extern void hfs_mark_mdb_dirty(struct super_block *sb);
+2 -1
fs/hfs/inode.c
··· 45 45 } 46 46 47 47 int hfs_write_begin(const struct kiocb *iocb, struct address_space *mapping, 48 - loff_t pos, unsigned len, struct folio **foliop, void **fsdata) 48 + loff_t pos, unsigned int len, struct folio **foliop, 49 + void **fsdata) 49 50 { 50 51 int ret; 51 52
+1 -1
fs/hfsplus/bfind.c
··· 210 210 return res; 211 211 } 212 212 213 - int hfs_brec_read(struct hfs_find_data *fd, void *rec, int rec_len) 213 + int hfs_brec_read(struct hfs_find_data *fd, void *rec, u32 rec_len) 214 214 { 215 215 int res; 216 216
+30 -30
fs/hfsplus/bnode.c
··· 20 20 21 21 22 22 /* Copy a specified range of bytes from the raw data of a node */ 23 - void hfs_bnode_read(struct hfs_bnode *node, void *buf, int off, int len) 23 + void hfs_bnode_read(struct hfs_bnode *node, void *buf, u32 off, u32 len) 24 24 { 25 25 struct page **pagep; 26 - int l; 26 + u32 l; 27 27 28 28 if (!is_bnode_offset_valid(node, off)) 29 29 return; ··· 31 31 if (len == 0) { 32 32 pr_err("requested zero length: " 33 33 "NODE: id %u, type %#x, height %u, " 34 - "node_size %u, offset %d, len %d\n", 34 + "node_size %u, offset %u, len %u\n", 35 35 node->this, node->type, node->height, 36 36 node->tree->node_size, off, len); 37 37 return; ··· 43 43 pagep = node->page + (off >> PAGE_SHIFT); 44 44 off &= ~PAGE_MASK; 45 45 46 - l = min_t(int, len, PAGE_SIZE - off); 46 + l = min_t(u32, len, PAGE_SIZE - off); 47 47 memcpy_from_page(buf, *pagep, off, l); 48 48 49 49 while ((len -= l) != 0) { 50 50 buf += l; 51 - l = min_t(int, len, PAGE_SIZE); 51 + l = min_t(u32, len, PAGE_SIZE); 52 52 memcpy_from_page(buf, *++pagep, 0, l); 53 53 } 54 54 } 55 55 56 - u16 hfs_bnode_read_u16(struct hfs_bnode *node, int off) 56 + u16 hfs_bnode_read_u16(struct hfs_bnode *node, u32 off) 57 57 { 58 58 __be16 data; 59 59 /* TODO: optimize later... */ ··· 61 61 return be16_to_cpu(data); 62 62 } 63 63 64 - u8 hfs_bnode_read_u8(struct hfs_bnode *node, int off) 64 + u8 hfs_bnode_read_u8(struct hfs_bnode *node, u32 off) 65 65 { 66 66 u8 data; 67 67 /* TODO: optimize later... */ ··· 69 69 return data; 70 70 } 71 71 72 - void hfs_bnode_read_key(struct hfs_bnode *node, void *key, int off) 72 + void hfs_bnode_read_key(struct hfs_bnode *node, void *key, u32 off) 73 73 { 74 74 struct hfs_btree *tree; 75 - int key_len; 75 + u32 key_len; 76 76 77 77 tree = node->tree; 78 78 if (node->type == HFS_NODE_LEAF || ··· 84 84 85 85 if (key_len > sizeof(hfsplus_btree_key) || key_len < 1) { 86 86 memset(key, 0, sizeof(hfsplus_btree_key)); 87 - pr_err("hfsplus: Invalid key length: %d\n", key_len); 87 + pr_err("hfsplus: Invalid key length: %u\n", key_len); 88 88 return; 89 89 } 90 90 91 91 hfs_bnode_read(node, key, off, key_len); 92 92 } 93 93 94 - void hfs_bnode_write(struct hfs_bnode *node, void *buf, int off, int len) 94 + void hfs_bnode_write(struct hfs_bnode *node, void *buf, u32 off, u32 len) 95 95 { 96 96 struct page **pagep; 97 - int l; 97 + u32 l; 98 98 99 99 if (!is_bnode_offset_valid(node, off)) 100 100 return; ··· 102 102 if (len == 0) { 103 103 pr_err("requested zero length: " 104 104 "NODE: id %u, type %#x, height %u, " 105 - "node_size %u, offset %d, len %d\n", 105 + "node_size %u, offset %u, len %u\n", 106 106 node->this, node->type, node->height, 107 107 node->tree->node_size, off, len); 108 108 return; ··· 114 114 pagep = node->page + (off >> PAGE_SHIFT); 115 115 off &= ~PAGE_MASK; 116 116 117 - l = min_t(int, len, PAGE_SIZE - off); 117 + l = min_t(u32, len, PAGE_SIZE - off); 118 118 memcpy_to_page(*pagep, off, buf, l); 119 119 set_page_dirty(*pagep); 120 120 121 121 while ((len -= l) != 0) { 122 122 buf += l; 123 - l = min_t(int, len, PAGE_SIZE); 123 + l = min_t(u32, len, PAGE_SIZE); 124 124 memcpy_to_page(*++pagep, 0, buf, l); 125 125 set_page_dirty(*pagep); 126 126 } 127 127 } 128 128 129 - void hfs_bnode_write_u16(struct hfs_bnode *node, int off, u16 data) 129 + void hfs_bnode_write_u16(struct hfs_bnode *node, u32 off, u16 data) 130 130 { 131 131 __be16 v = cpu_to_be16(data); 132 132 /* TODO: optimize later... */ 133 133 hfs_bnode_write(node, &v, off, 2); 134 134 } 135 135 136 - void hfs_bnode_clear(struct hfs_bnode *node, int off, int len) 136 + void hfs_bnode_clear(struct hfs_bnode *node, u32 off, u32 len) 137 137 { 138 138 struct page **pagep; 139 - int l; 139 + u32 l; 140 140 141 141 if (!is_bnode_offset_valid(node, off)) 142 142 return; ··· 144 144 if (len == 0) { 145 145 pr_err("requested zero length: " 146 146 "NODE: id %u, type %#x, height %u, " 147 - "node_size %u, offset %d, len %d\n", 147 + "node_size %u, offset %u, len %u\n", 148 148 node->this, node->type, node->height, 149 149 node->tree->node_size, off, len); 150 150 return; ··· 156 156 pagep = node->page + (off >> PAGE_SHIFT); 157 157 off &= ~PAGE_MASK; 158 158 159 - l = min_t(int, len, PAGE_SIZE - off); 159 + l = min_t(u32, len, PAGE_SIZE - off); 160 160 memzero_page(*pagep, off, l); 161 161 set_page_dirty(*pagep); 162 162 163 163 while ((len -= l) != 0) { 164 - l = min_t(int, len, PAGE_SIZE); 164 + l = min_t(u32, len, PAGE_SIZE); 165 165 memzero_page(*++pagep, 0, l); 166 166 set_page_dirty(*pagep); 167 167 } 168 168 } 169 169 170 - void hfs_bnode_copy(struct hfs_bnode *dst_node, int dst, 171 - struct hfs_bnode *src_node, int src, int len) 170 + void hfs_bnode_copy(struct hfs_bnode *dst_node, u32 dst, 171 + struct hfs_bnode *src_node, u32 src, u32 len) 172 172 { 173 173 struct page **src_page, **dst_page; 174 - int l; 174 + u32 l; 175 175 176 176 hfs_dbg("dst %u, src %u, len %u\n", dst, src, len); 177 177 if (!len) ··· 188 188 dst &= ~PAGE_MASK; 189 189 190 190 if (src == dst) { 191 - l = min_t(int, len, PAGE_SIZE - src); 191 + l = min_t(u32, len, PAGE_SIZE - src); 192 192 memcpy_page(*dst_page, src, *src_page, src, l); 193 193 set_page_dirty(*dst_page); 194 194 195 195 while ((len -= l) != 0) { 196 - l = min_t(int, len, PAGE_SIZE); 196 + l = min_t(u32, len, PAGE_SIZE); 197 197 memcpy_page(*++dst_page, 0, *++src_page, 0, l); 198 198 set_page_dirty(*dst_page); 199 199 } ··· 225 225 } 226 226 } 227 227 228 - void hfs_bnode_move(struct hfs_bnode *node, int dst, int src, int len) 228 + void hfs_bnode_move(struct hfs_bnode *node, u32 dst, u32 src, u32 len) 229 229 { 230 230 struct page **src_page, **dst_page; 231 231 void *src_ptr, *dst_ptr; 232 - int l; 232 + u32 l; 233 233 234 234 hfs_dbg("dst %u, src %u, len %u\n", dst, src, len); 235 235 if (!len) ··· 299 299 dst &= ~PAGE_MASK; 300 300 301 301 if (src == dst) { 302 - l = min_t(int, len, PAGE_SIZE - src); 302 + l = min_t(u32, len, PAGE_SIZE - src); 303 303 304 304 dst_ptr = kmap_local_page(*dst_page) + src; 305 305 src_ptr = kmap_local_page(*src_page) + src; ··· 309 309 kunmap_local(dst_ptr); 310 310 311 311 while ((len -= l) != 0) { 312 - l = min_t(int, len, PAGE_SIZE); 312 + l = min_t(u32, len, PAGE_SIZE); 313 313 dst_ptr = kmap_local_page(*++dst_page); 314 314 src_ptr = kmap_local_page(*++src_page); 315 315 memmove(dst_ptr, src_ptr, l);
+1 -1
fs/hfsplus/brec.c
··· 60 60 return retval; 61 61 } 62 62 63 - int hfs_brec_insert(struct hfs_find_data *fd, void *entry, int entry_len) 63 + int hfs_brec_insert(struct hfs_find_data *fd, void *entry, u32 entry_len) 64 64 { 65 65 struct hfs_btree *tree; 66 66 struct hfs_bnode *node, *new_node;
+1 -1
fs/hfsplus/btree.c
··· 344 344 } 345 345 346 346 /* Make sure @tree has enough space for the @rsvd_nodes */ 347 - int hfs_bmap_reserve(struct hfs_btree *tree, int rsvd_nodes) 347 + int hfs_bmap_reserve(struct hfs_btree *tree, u32 rsvd_nodes) 348 348 { 349 349 struct inode *inode = tree->inode; 350 350 struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
+19 -19
fs/hfsplus/hfsplus_fs.h
··· 357 357 struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id); 358 358 void hfs_btree_close(struct hfs_btree *tree); 359 359 int hfs_btree_write(struct hfs_btree *tree); 360 - int hfs_bmap_reserve(struct hfs_btree *tree, int rsvd_nodes); 360 + int hfs_bmap_reserve(struct hfs_btree *tree, u32 rsvd_nodes); 361 361 struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree); 362 362 void hfs_bmap_free(struct hfs_bnode *node); 363 363 364 364 /* bnode.c */ 365 - void hfs_bnode_read(struct hfs_bnode *node, void *buf, int off, int len); 366 - u16 hfs_bnode_read_u16(struct hfs_bnode *node, int off); 367 - u8 hfs_bnode_read_u8(struct hfs_bnode *node, int off); 368 - void hfs_bnode_read_key(struct hfs_bnode *node, void *key, int off); 369 - void hfs_bnode_write(struct hfs_bnode *node, void *buf, int off, int len); 370 - void hfs_bnode_write_u16(struct hfs_bnode *node, int off, u16 data); 371 - void hfs_bnode_clear(struct hfs_bnode *node, int off, int len); 372 - void hfs_bnode_copy(struct hfs_bnode *dst_node, int dst, 373 - struct hfs_bnode *src_node, int src, int len); 374 - void hfs_bnode_move(struct hfs_bnode *node, int dst, int src, int len); 365 + void hfs_bnode_read(struct hfs_bnode *node, void *buf, u32 off, u32 len); 366 + u16 hfs_bnode_read_u16(struct hfs_bnode *node, u32 off); 367 + u8 hfs_bnode_read_u8(struct hfs_bnode *node, u32 off); 368 + void hfs_bnode_read_key(struct hfs_bnode *node, void *key, u32 off); 369 + void hfs_bnode_write(struct hfs_bnode *node, void *buf, u32 off, u32 len); 370 + void hfs_bnode_write_u16(struct hfs_bnode *node, u32 off, u16 data); 371 + void hfs_bnode_clear(struct hfs_bnode *node, u32 off, u32 len); 372 + void hfs_bnode_copy(struct hfs_bnode *dst_node, u32 dst, 373 + struct hfs_bnode *src_node, u32 src, u32 len); 374 + void hfs_bnode_move(struct hfs_bnode *node, u32 dst, u32 src, u32 len); 375 375 void hfs_bnode_dump(struct hfs_bnode *node); 376 376 void hfs_bnode_unlink(struct hfs_bnode *node); 377 377 struct hfs_bnode *hfs_bnode_findhash(struct hfs_btree *tree, u32 cnid); ··· 386 386 /* brec.c */ 387 387 u16 hfs_brec_lenoff(struct hfs_bnode *node, u16 rec, u16 *off); 388 388 u16 hfs_brec_keylen(struct hfs_bnode *node, u16 rec); 389 - int hfs_brec_insert(struct hfs_find_data *fd, void *entry, int entry_len); 389 + int hfs_brec_insert(struct hfs_find_data *fd, void *entry, u32 entry_len); 390 390 int hfs_brec_remove(struct hfs_find_data *fd); 391 391 392 392 /* bfind.c */ ··· 399 399 int __hfs_brec_find(struct hfs_bnode *bnode, struct hfs_find_data *fd, 400 400 search_strategy_t rec_found); 401 401 int hfs_brec_find(struct hfs_find_data *fd, search_strategy_t do_key_compare); 402 - int hfs_brec_read(struct hfs_find_data *fd, void *rec, int rec_len); 402 + int hfs_brec_read(struct hfs_find_data *fd, void *rec, u32 rec_len); 403 403 int hfs_brec_goto(struct hfs_find_data *fd, int cnt); 404 404 405 405 /* catalog.c */ ··· 549 549 } 550 550 551 551 static inline 552 - bool is_bnode_offset_valid(struct hfs_bnode *node, int off) 552 + bool is_bnode_offset_valid(struct hfs_bnode *node, u32 off) 553 553 { 554 554 bool is_valid = off < node->tree->node_size; 555 555 556 556 if (!is_valid) { 557 557 pr_err("requested invalid offset: " 558 558 "NODE: id %u, type %#x, height %u, " 559 - "node_size %u, offset %d\n", 559 + "node_size %u, offset %u\n", 560 560 node->this, node->type, node->height, 561 561 node->tree->node_size, off); 562 562 } ··· 565 565 } 566 566 567 567 static inline 568 - int check_and_correct_requested_length(struct hfs_bnode *node, int off, int len) 568 + u32 check_and_correct_requested_length(struct hfs_bnode *node, u32 off, u32 len) 569 569 { 570 570 unsigned int node_size; 571 571 ··· 575 575 node_size = node->tree->node_size; 576 576 577 577 if ((off + len) > node_size) { 578 - int new_len = (int)node_size - off; 578 + u32 new_len = node_size - off; 579 579 580 580 pr_err("requested length has been corrected: " 581 581 "NODE: id %u, type %#x, height %u, " 582 - "node_size %u, offset %d, " 583 - "requested_len %d, corrected_len %d\n", 582 + "node_size %u, offset %u, " 583 + "requested_len %u, corrected_len %u\n", 584 584 node->this, node->type, node->height, 585 585 node->tree->node_size, off, len, new_len); 586 586