18
18
#include "hfsplus_fs.h"
19
19
#include "hfsplus_raw.h"
20
20
21
+ static inline
22
+ bool is_bnode_offset_valid (struct hfs_bnode * node , int off )
23
+ {
24
+ bool is_valid = off < node -> tree -> node_size ;
25
+
26
+ if (!is_valid ) {
27
+ pr_err ("requested invalid offset: "
28
+ "NODE: id %u, type %#x, height %u, "
29
+ "node_size %u, offset %d\n" ,
30
+ node -> this , node -> type , node -> height ,
31
+ node -> tree -> node_size , off );
32
+ }
33
+
34
+ return is_valid ;
35
+ }
36
+
37
+ static inline
38
+ int check_and_correct_requested_length (struct hfs_bnode * node , int off , int len )
39
+ {
40
+ unsigned int node_size ;
41
+
42
+ if (!is_bnode_offset_valid (node , off ))
43
+ return 0 ;
44
+
45
+ node_size = node -> tree -> node_size ;
46
+
47
+ if ((off + len ) > node_size ) {
48
+ int new_len = (int )node_size - off ;
49
+
50
+ pr_err ("requested length has been corrected: "
51
+ "NODE: id %u, type %#x, height %u, "
52
+ "node_size %u, offset %d, "
53
+ "requested_len %d, corrected_len %d\n" ,
54
+ node -> this , node -> type , node -> height ,
55
+ node -> tree -> node_size , off , len , new_len );
56
+
57
+ return new_len ;
58
+ }
59
+
60
+ return len ;
61
+ }
62
+
21
63
/* Copy a specified range of bytes from the raw data of a node */
22
64
void hfs_bnode_read (struct hfs_bnode * node , void * buf , int off , int len )
23
65
{
24
66
struct page * * pagep ;
25
67
int l ;
26
68
69
+ if (!is_bnode_offset_valid (node , off ))
70
+ return ;
71
+
72
+ if (len == 0 ) {
73
+ pr_err ("requested zero length: "
74
+ "NODE: id %u, type %#x, height %u, "
75
+ "node_size %u, offset %d, len %d\n" ,
76
+ node -> this , node -> type , node -> height ,
77
+ node -> tree -> node_size , off , len );
78
+ return ;
79
+ }
80
+
81
+ len = check_and_correct_requested_length (node , off , len );
82
+
27
83
off += node -> page_offset ;
28
84
pagep = node -> page + (off >> PAGE_SHIFT );
29
85
off &= ~PAGE_MASK ;
@@ -81,6 +137,20 @@ void hfs_bnode_write(struct hfs_bnode *node, void *buf, int off, int len)
81
137
struct page * * pagep ;
82
138
int l ;
83
139
140
+ if (!is_bnode_offset_valid (node , off ))
141
+ return ;
142
+
143
+ if (len == 0 ) {
144
+ pr_err ("requested zero length: "
145
+ "NODE: id %u, type %#x, height %u, "
146
+ "node_size %u, offset %d, len %d\n" ,
147
+ node -> this , node -> type , node -> height ,
148
+ node -> tree -> node_size , off , len );
149
+ return ;
150
+ }
151
+
152
+ len = check_and_correct_requested_length (node , off , len );
153
+
84
154
off += node -> page_offset ;
85
155
pagep = node -> page + (off >> PAGE_SHIFT );
86
156
off &= ~PAGE_MASK ;
@@ -109,6 +179,20 @@ void hfs_bnode_clear(struct hfs_bnode *node, int off, int len)
109
179
struct page * * pagep ;
110
180
int l ;
111
181
182
+ if (!is_bnode_offset_valid (node , off ))
183
+ return ;
184
+
185
+ if (len == 0 ) {
186
+ pr_err ("requested zero length: "
187
+ "NODE: id %u, type %#x, height %u, "
188
+ "node_size %u, offset %d, len %d\n" ,
189
+ node -> this , node -> type , node -> height ,
190
+ node -> tree -> node_size , off , len );
191
+ return ;
192
+ }
193
+
194
+ len = check_and_correct_requested_length (node , off , len );
195
+
112
196
off += node -> page_offset ;
113
197
pagep = node -> page + (off >> PAGE_SHIFT );
114
198
off &= ~PAGE_MASK ;
@@ -133,6 +217,10 @@ void hfs_bnode_copy(struct hfs_bnode *dst_node, int dst,
133
217
hfs_dbg (BNODE_MOD , "copybytes: %u,%u,%u\n" , dst , src , len );
134
218
if (!len )
135
219
return ;
220
+
221
+ len = check_and_correct_requested_length (src_node , src , len );
222
+ len = check_and_correct_requested_length (dst_node , dst , len );
223
+
136
224
src += src_node -> page_offset ;
137
225
dst += dst_node -> page_offset ;
138
226
src_page = src_node -> page + (src >> PAGE_SHIFT );
@@ -187,6 +275,10 @@ void hfs_bnode_move(struct hfs_bnode *node, int dst, int src, int len)
187
275
hfs_dbg (BNODE_MOD , "movebytes: %u,%u,%u\n" , dst , src , len );
188
276
if (!len )
189
277
return ;
278
+
279
+ len = check_and_correct_requested_length (node , src , len );
280
+ len = check_and_correct_requested_length (node , dst , len );
281
+
190
282
src += node -> page_offset ;
191
283
dst += node -> page_offset ;
192
284
if (dst > src ) {
0 commit comments