aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQu Wenruo <wqu@suse.com>2017-11-07 19:54:26 -0500
committerDavid Sterba <dsterba@suse.com>2018-01-22 10:08:12 -0500
commitbae15d95e247f94ceb32caaf13d1d71ecbfc8735 (patch)
tree79a144412a3b0a8ecb9f5631d6f09a5a4d342625
parentad7b0368f33cffe67fecd302028915926e50ef7e (diff)
btrfs: Cleanup existing name_len checks
Since tree-checker has verified leaf when reading from disk, we don't need the existing verify_dir_item() or btrfs_is_name_len_valid() checks. Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: Nikolay Borisov <nborisov@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r--fs/btrfs/ctree.h5
-rw-r--r--fs/btrfs/dir-item.c108
-rw-r--r--fs/btrfs/export.c5
-rw-r--r--fs/btrfs/inode.c4
-rw-r--r--fs/btrfs/props.c7
-rw-r--r--fs/btrfs/root-tree.c7
-rw-r--r--fs/btrfs/send.c6
-rw-r--r--fs/btrfs/tree-log.c47
-rw-r--r--fs/btrfs/xattr.c6
9 files changed, 9 insertions, 186 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index a56d00311578..09b72b6996ce 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -3060,15 +3060,10 @@ struct btrfs_dir_item *btrfs_lookup_xattr(struct btrfs_trans_handle *trans,
3060 struct btrfs_path *path, u64 dir, 3060 struct btrfs_path *path, u64 dir,
3061 const char *name, u16 name_len, 3061 const char *name, u16 name_len,
3062 int mod); 3062 int mod);
3063int verify_dir_item(struct btrfs_fs_info *fs_info,
3064 struct extent_buffer *leaf, int slot,
3065 struct btrfs_dir_item *dir_item);
3066struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_fs_info *fs_info, 3063struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_fs_info *fs_info,
3067 struct btrfs_path *path, 3064 struct btrfs_path *path,
3068 const char *name, 3065 const char *name,
3069 int name_len); 3066 int name_len);
3070bool btrfs_is_name_len_valid(struct extent_buffer *leaf, int slot,
3071 unsigned long start, u16 name_len);
3072 3067
3073/* orphan.c */ 3068/* orphan.c */
3074int btrfs_insert_orphan_item(struct btrfs_trans_handle *trans, 3069int btrfs_insert_orphan_item(struct btrfs_trans_handle *trans,
diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c
index 41cb9196eaa8..cbe421605cd5 100644
--- a/fs/btrfs/dir-item.c
+++ b/fs/btrfs/dir-item.c
@@ -403,8 +403,6 @@ struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_fs_info *fs_info,
403 btrfs_dir_data_len(leaf, dir_item); 403 btrfs_dir_data_len(leaf, dir_item);
404 name_ptr = (unsigned long)(dir_item + 1); 404 name_ptr = (unsigned long)(dir_item + 1);
405 405
406 if (verify_dir_item(fs_info, leaf, path->slots[0], dir_item))
407 return NULL;
408 if (btrfs_dir_name_len(leaf, dir_item) == name_len && 406 if (btrfs_dir_name_len(leaf, dir_item) == name_len &&
409 memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0) 407 memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0)
410 return dir_item; 408 return dir_item;
@@ -450,109 +448,3 @@ int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans,
450 } 448 }
451 return ret; 449 return ret;
452} 450}
453
454int verify_dir_item(struct btrfs_fs_info *fs_info,
455 struct extent_buffer *leaf,
456 int slot,
457 struct btrfs_dir_item *dir_item)
458{
459 u16 namelen = BTRFS_NAME_LEN;
460 int ret;
461 u8 type = btrfs_dir_type(leaf, dir_item);
462
463 if (type >= BTRFS_FT_MAX) {
464 btrfs_crit(fs_info, "invalid dir item type: %d", (int)type);
465 return 1;
466 }
467
468 if (type == BTRFS_FT_XATTR)
469 namelen = XATTR_NAME_MAX;
470
471 if (btrfs_dir_name_len(leaf, dir_item) > namelen) {
472 btrfs_crit(fs_info, "invalid dir item name len: %u",
473 (unsigned)btrfs_dir_name_len(leaf, dir_item));
474 return 1;
475 }
476
477 namelen = btrfs_dir_name_len(leaf, dir_item);
478 ret = btrfs_is_name_len_valid(leaf, slot,
479 (unsigned long)(dir_item + 1), namelen);
480 if (!ret)
481 return 1;
482
483 /* BTRFS_MAX_XATTR_SIZE is the same for all dir items */
484 if ((btrfs_dir_data_len(leaf, dir_item) +
485 btrfs_dir_name_len(leaf, dir_item)) >
486 BTRFS_MAX_XATTR_SIZE(fs_info)) {
487 btrfs_crit(fs_info, "invalid dir item name + data len: %u + %u",
488 (unsigned)btrfs_dir_name_len(leaf, dir_item),
489 (unsigned)btrfs_dir_data_len(leaf, dir_item));
490 return 1;
491 }
492
493 return 0;
494}
495
496bool btrfs_is_name_len_valid(struct extent_buffer *leaf, int slot,
497 unsigned long start, u16 name_len)
498{
499 struct btrfs_fs_info *fs_info = leaf->fs_info;
500 struct btrfs_key key;
501 u32 read_start;
502 u32 read_end;
503 u32 item_start;
504 u32 item_end;
505 u32 size;
506 bool ret = true;
507
508 ASSERT(start > BTRFS_LEAF_DATA_OFFSET);
509
510 read_start = start - BTRFS_LEAF_DATA_OFFSET;
511 read_end = read_start + name_len;
512 item_start = btrfs_item_offset_nr(leaf, slot);
513 item_end = btrfs_item_end_nr(leaf, slot);
514
515 btrfs_item_key_to_cpu(leaf, &key, slot);
516
517 switch (key.type) {
518 case BTRFS_DIR_ITEM_KEY:
519 case BTRFS_XATTR_ITEM_KEY:
520 case BTRFS_DIR_INDEX_KEY:
521 size = sizeof(struct btrfs_dir_item);
522 break;
523 case BTRFS_INODE_REF_KEY:
524 size = sizeof(struct btrfs_inode_ref);
525 break;
526 case BTRFS_INODE_EXTREF_KEY:
527 size = sizeof(struct btrfs_inode_extref);
528 break;
529 case BTRFS_ROOT_REF_KEY:
530 case BTRFS_ROOT_BACKREF_KEY:
531 size = sizeof(struct btrfs_root_ref);
532 break;
533 default:
534 ret = false;
535 goto out;
536 }
537
538 if (read_start < item_start) {
539 ret = false;
540 goto out;
541 }
542 if (read_end > item_end) {
543 ret = false;
544 goto out;
545 }
546
547 /* there shall be item(s) before name */
548 if (read_start - item_start < size) {
549 ret = false;
550 goto out;
551 }
552
553out:
554 if (!ret)
555 btrfs_crit(fs_info, "invalid dir item name len: %u",
556 (unsigned int)name_len);
557 return ret;
558}
diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c
index 3aeb5770f896..ddaccad469f8 100644
--- a/fs/btrfs/export.c
+++ b/fs/btrfs/export.c
@@ -283,11 +283,6 @@ static int btrfs_get_name(struct dentry *parent, char *name,
283 name_len = btrfs_inode_ref_name_len(leaf, iref); 283 name_len = btrfs_inode_ref_name_len(leaf, iref);
284 } 284 }
285 285
286 ret = btrfs_is_name_len_valid(leaf, path->slots[0], name_ptr, name_len);
287 if (!ret) {
288 btrfs_free_path(path);
289 return -EIO;
290 }
291 read_extent_buffer(leaf, name, name_ptr, name_len); 286 read_extent_buffer(leaf, name, name_ptr, name_len);
292 btrfs_free_path(path); 287 btrfs_free_path(path);
293 288
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 2e92c582cda0..ff91b2e3979a 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -5907,7 +5907,6 @@ static int btrfs_filldir(void *addr, int entries, struct dir_context *ctx)
5907static int btrfs_real_readdir(struct file *file, struct dir_context *ctx) 5907static int btrfs_real_readdir(struct file *file, struct dir_context *ctx)
5908{ 5908{
5909 struct inode *inode = file_inode(file); 5909 struct inode *inode = file_inode(file);
5910 struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
5911 struct btrfs_root *root = BTRFS_I(inode)->root; 5910 struct btrfs_root *root = BTRFS_I(inode)->root;
5912 struct btrfs_file_private *private = file->private_data; 5911 struct btrfs_file_private *private = file->private_data;
5913 struct btrfs_dir_item *di; 5912 struct btrfs_dir_item *di;
@@ -5975,9 +5974,6 @@ again:
5975 if (btrfs_should_delete_dir_index(&del_list, found_key.offset)) 5974 if (btrfs_should_delete_dir_index(&del_list, found_key.offset))
5976 goto next; 5975 goto next;
5977 di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item); 5976 di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
5978 if (verify_dir_item(fs_info, leaf, slot, di))
5979 goto next;
5980
5981 name_len = btrfs_dir_name_len(leaf, di); 5977 name_len = btrfs_dir_name_len(leaf, di);
5982 if ((total_len + sizeof(struct dir_entry) + name_len) >= 5978 if ((total_len + sizeof(struct dir_entry) + name_len) >=
5983 PAGE_SIZE) { 5979 PAGE_SIZE) {
diff --git a/fs/btrfs/props.c b/fs/btrfs/props.c
index f6a05f836629..c39a940d0c75 100644
--- a/fs/btrfs/props.c
+++ b/fs/btrfs/props.c
@@ -164,7 +164,6 @@ static int iterate_object_props(struct btrfs_root *root,
164 size_t), 164 size_t),
165 void *ctx) 165 void *ctx)
166{ 166{
167 struct btrfs_fs_info *fs_info = root->fs_info;
168 int ret; 167 int ret;
169 char *name_buf = NULL; 168 char *name_buf = NULL;
170 char *value_buf = NULL; 169 char *value_buf = NULL;
@@ -215,12 +214,6 @@ static int iterate_object_props(struct btrfs_root *root,
215 name_ptr = (unsigned long)(di + 1); 214 name_ptr = (unsigned long)(di + 1);
216 data_ptr = name_ptr + name_len; 215 data_ptr = name_ptr + name_len;
217 216
218 if (verify_dir_item(fs_info, leaf,
219 path->slots[0], di)) {
220 ret = -EIO;
221 goto out;
222 }
223
224 if (name_len <= XATTR_BTRFS_PREFIX_LEN || 217 if (name_len <= XATTR_BTRFS_PREFIX_LEN ||
225 memcmp_extent_buffer(leaf, XATTR_BTRFS_PREFIX, 218 memcmp_extent_buffer(leaf, XATTR_BTRFS_PREFIX,
226 name_ptr, 219 name_ptr,
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c
index 3338407ef0f0..aab0194efe46 100644
--- a/fs/btrfs/root-tree.c
+++ b/fs/btrfs/root-tree.c
@@ -387,13 +387,6 @@ again:
387 WARN_ON(btrfs_root_ref_dirid(leaf, ref) != dirid); 387 WARN_ON(btrfs_root_ref_dirid(leaf, ref) != dirid);
388 WARN_ON(btrfs_root_ref_name_len(leaf, ref) != name_len); 388 WARN_ON(btrfs_root_ref_name_len(leaf, ref) != name_len);
389 ptr = (unsigned long)(ref + 1); 389 ptr = (unsigned long)(ref + 1);
390 ret = btrfs_is_name_len_valid(leaf, path->slots[0], ptr,
391 name_len);
392 if (!ret) {
393 err = -EIO;
394 goto out;
395 }
396
397 WARN_ON(memcmp_extent_buffer(leaf, name, ptr, name_len)); 390 WARN_ON(memcmp_extent_buffer(leaf, name, ptr, name_len));
398 *sequence = btrfs_root_ref_sequence(leaf, ref); 391 *sequence = btrfs_root_ref_sequence(leaf, ref);
399 392
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 20d3300bd268..f306c608dc28 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -1059,12 +1059,6 @@ static int iterate_dir_item(struct btrfs_root *root, struct btrfs_path *path,
1059 } 1059 }
1060 } 1060 }
1061 1061
1062 ret = btrfs_is_name_len_valid(eb, path->slots[0],
1063 (unsigned long)(di + 1), name_len + data_len);
1064 if (!ret) {
1065 ret = -EIO;
1066 goto out;
1067 }
1068 if (name_len + data_len > buf_len) { 1062 if (name_len + data_len > buf_len) {
1069 buf_len = name_len + data_len; 1063 buf_len = name_len + data_len;
1070 if (is_vmalloc_addr(buf)) { 1064 if (is_vmalloc_addr(buf)) {
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 7bf9b31561db..a806182dfea6 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -1173,19 +1173,15 @@ next:
1173 return 0; 1173 return 0;
1174} 1174}
1175 1175
1176static int extref_get_fields(struct extent_buffer *eb, int slot, 1176static int extref_get_fields(struct extent_buffer *eb, unsigned long ref_ptr,
1177 unsigned long ref_ptr, u32 *namelen, char **name, 1177 u32 *namelen, char **name, u64 *index,
1178 u64 *index, u64 *parent_objectid) 1178 u64 *parent_objectid)
1179{ 1179{
1180 struct btrfs_inode_extref *extref; 1180 struct btrfs_inode_extref *extref;
1181 1181
1182 extref = (struct btrfs_inode_extref *)ref_ptr; 1182 extref = (struct btrfs_inode_extref *)ref_ptr;
1183 1183
1184 *namelen = btrfs_inode_extref_name_len(eb, extref); 1184 *namelen = btrfs_inode_extref_name_len(eb, extref);
1185 if (!btrfs_is_name_len_valid(eb, slot, (unsigned long)&extref->name,
1186 *namelen))
1187 return -EIO;
1188
1189 *name = kmalloc(*namelen, GFP_NOFS); 1185 *name = kmalloc(*namelen, GFP_NOFS);
1190 if (*name == NULL) 1186 if (*name == NULL)
1191 return -ENOMEM; 1187 return -ENOMEM;
@@ -1200,19 +1196,14 @@ static int extref_get_fields(struct extent_buffer *eb, int slot,
1200 return 0; 1196 return 0;
1201} 1197}
1202 1198
1203static int ref_get_fields(struct extent_buffer *eb, int slot, 1199static int ref_get_fields(struct extent_buffer *eb, unsigned long ref_ptr,
1204 unsigned long ref_ptr, u32 *namelen, char **name, 1200 u32 *namelen, char **name, u64 *index)
1205 u64 *index)
1206{ 1201{
1207 struct btrfs_inode_ref *ref; 1202 struct btrfs_inode_ref *ref;
1208 1203
1209 ref = (struct btrfs_inode_ref *)ref_ptr; 1204 ref = (struct btrfs_inode_ref *)ref_ptr;
1210 1205
1211 *namelen = btrfs_inode_ref_name_len(eb, ref); 1206 *namelen = btrfs_inode_ref_name_len(eb, ref);
1212 if (!btrfs_is_name_len_valid(eb, slot, (unsigned long)(ref + 1),
1213 *namelen))
1214 return -EIO;
1215
1216 *name = kmalloc(*namelen, GFP_NOFS); 1207 *name = kmalloc(*namelen, GFP_NOFS);
1217 if (*name == NULL) 1208 if (*name == NULL)
1218 return -ENOMEM; 1209 return -ENOMEM;
@@ -1287,8 +1278,8 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
1287 1278
1288 while (ref_ptr < ref_end) { 1279 while (ref_ptr < ref_end) {
1289 if (log_ref_ver) { 1280 if (log_ref_ver) {
1290 ret = extref_get_fields(eb, slot, ref_ptr, &namelen, 1281 ret = extref_get_fields(eb, ref_ptr, &namelen, &name,
1291 &name, &ref_index, &parent_objectid); 1282 &ref_index, &parent_objectid);
1292 /* 1283 /*
1293 * parent object can change from one array 1284 * parent object can change from one array
1294 * item to another. 1285 * item to another.
@@ -1300,8 +1291,8 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
1300 goto out; 1291 goto out;
1301 } 1292 }
1302 } else { 1293 } else {
1303 ret = ref_get_fields(eb, slot, ref_ptr, &namelen, 1294 ret = ref_get_fields(eb, ref_ptr, &namelen, &name,
1304 &name, &ref_index); 1295 &ref_index);
1305 } 1296 }
1306 if (ret) 1297 if (ret)
1307 goto out; 1298 goto out;
@@ -1835,7 +1826,6 @@ static noinline int replay_one_dir_item(struct btrfs_trans_handle *trans,
1835 struct extent_buffer *eb, int slot, 1826 struct extent_buffer *eb, int slot,
1836 struct btrfs_key *key) 1827 struct btrfs_key *key)
1837{ 1828{
1838 struct btrfs_fs_info *fs_info = root->fs_info;
1839 int ret = 0; 1829 int ret = 0;
1840 u32 item_size = btrfs_item_size_nr(eb, slot); 1830 u32 item_size = btrfs_item_size_nr(eb, slot);
1841 struct btrfs_dir_item *di; 1831 struct btrfs_dir_item *di;
@@ -1848,8 +1838,6 @@ static noinline int replay_one_dir_item(struct btrfs_trans_handle *trans,
1848 ptr_end = ptr + item_size; 1838 ptr_end = ptr + item_size;
1849 while (ptr < ptr_end) { 1839 while (ptr < ptr_end) {
1850 di = (struct btrfs_dir_item *)ptr; 1840 di = (struct btrfs_dir_item *)ptr;
1851 if (verify_dir_item(fs_info, eb, slot, di))
1852 return -EIO;
1853 name_len = btrfs_dir_name_len(eb, di); 1841 name_len = btrfs_dir_name_len(eb, di);
1854 ret = replay_one_name(trans, root, path, eb, di, key); 1842 ret = replay_one_name(trans, root, path, eb, di, key);
1855 if (ret < 0) 1843 if (ret < 0)
@@ -2024,11 +2012,6 @@ again:
2024 ptr_end = ptr + item_size; 2012 ptr_end = ptr + item_size;
2025 while (ptr < ptr_end) { 2013 while (ptr < ptr_end) {
2026 di = (struct btrfs_dir_item *)ptr; 2014 di = (struct btrfs_dir_item *)ptr;
2027 if (verify_dir_item(fs_info, eb, slot, di)) {
2028 ret = -EIO;
2029 goto out;
2030 }
2031
2032 name_len = btrfs_dir_name_len(eb, di); 2015 name_len = btrfs_dir_name_len(eb, di);
2033 name = kmalloc(name_len, GFP_NOFS); 2016 name = kmalloc(name_len, GFP_NOFS);
2034 if (!name) { 2017 if (!name) {
@@ -2109,7 +2092,6 @@ static int replay_xattr_deletes(struct btrfs_trans_handle *trans,
2109 struct btrfs_path *path, 2092 struct btrfs_path *path,
2110 const u64 ino) 2093 const u64 ino)
2111{ 2094{
2112 struct btrfs_fs_info *fs_info = root->fs_info;
2113 struct btrfs_key search_key; 2095 struct btrfs_key search_key;
2114 struct btrfs_path *log_path; 2096 struct btrfs_path *log_path;
2115 int i; 2097 int i;
@@ -2151,11 +2133,6 @@ process_leaf:
2151 u32 this_len = sizeof(*di) + name_len + data_len; 2133 u32 this_len = sizeof(*di) + name_len + data_len;
2152 char *name; 2134 char *name;
2153 2135
2154 ret = verify_dir_item(fs_info, path->nodes[0], i, di);
2155 if (ret) {
2156 ret = -EIO;
2157 goto out;
2158 }
2159 name = kmalloc(name_len, GFP_NOFS); 2136 name = kmalloc(name_len, GFP_NOFS);
2160 if (!name) { 2137 if (!name) {
2161 ret = -ENOMEM; 2138 ret = -ENOMEM;
@@ -4572,12 +4549,6 @@ static int btrfs_check_ref_name_override(struct extent_buffer *eb,
4572 this_len = sizeof(*extref) + this_name_len; 4549 this_len = sizeof(*extref) + this_name_len;
4573 } 4550 }
4574 4551
4575 ret = btrfs_is_name_len_valid(eb, slot, name_ptr,
4576 this_name_len);
4577 if (!ret) {
4578 ret = -EIO;
4579 goto out;
4580 }
4581 if (this_name_len > name_len) { 4552 if (this_name_len > name_len) {
4582 char *new_name; 4553 char *new_name;
4583 4554
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c
index 2c7e53f9ff1b..ad298c248da4 100644
--- a/fs/btrfs/xattr.c
+++ b/fs/btrfs/xattr.c
@@ -267,7 +267,6 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
267{ 267{
268 struct btrfs_key key; 268 struct btrfs_key key;
269 struct inode *inode = d_inode(dentry); 269 struct inode *inode = d_inode(dentry);
270 struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
271 struct btrfs_root *root = BTRFS_I(inode)->root; 270 struct btrfs_root *root = BTRFS_I(inode)->root;
272 struct btrfs_path *path; 271 struct btrfs_path *path;
273 int ret = 0; 272 int ret = 0;
@@ -336,11 +335,6 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
336 u32 this_len = sizeof(*di) + name_len + data_len; 335 u32 this_len = sizeof(*di) + name_len + data_len;
337 unsigned long name_ptr = (unsigned long)(di + 1); 336 unsigned long name_ptr = (unsigned long)(di + 1);
338 337
339 if (verify_dir_item(fs_info, leaf, slot, di)) {
340 ret = -EIO;
341 goto err;
342 }
343
344 total_size += name_len + 1; 338 total_size += name_len + 1;
345 /* 339 /*
346 * We are just looking for how big our buffer needs to 340 * We are just looking for how big our buffer needs to