aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/dir-item.c
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2011-03-16 16:47:17 -0400
committerJosef Bacik <josef@redhat.com>2011-03-17 14:21:41 -0400
commit22a94d44bd6876a90630338229da6c0436d46593 (patch)
tree50e5c7dd52ccf9292240de995e5b42b1619bcd82 /fs/btrfs/dir-item.c
parent41415730a1050499fbd63b3f7dd59b3a4c3bb91a (diff)
Btrfs: add checks to verify dir items are correct
We need to make sure the dir items we get are valid dir items. So any time we try and read one check it with verify_dir_item, which will do various sanity checks to make sure it looks sane. Thanks, Signed-off-by: Josef Bacik <josef@redhat.com>
Diffstat (limited to 'fs/btrfs/dir-item.c')
-rw-r--r--fs/btrfs/dir-item.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c
index f0cad5ae5be7..02c97ad61b6d 100644
--- a/fs/btrfs/dir-item.c
+++ b/fs/btrfs/dir-item.c
@@ -377,6 +377,9 @@ struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root,
377 377
378 leaf = path->nodes[0]; 378 leaf = path->nodes[0];
379 dir_item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_dir_item); 379 dir_item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_dir_item);
380 if (verify_dir_item(root, leaf, dir_item))
381 return NULL;
382
380 total_len = btrfs_item_size_nr(leaf, path->slots[0]); 383 total_len = btrfs_item_size_nr(leaf, path->slots[0]);
381 while (cur < total_len) { 384 while (cur < total_len) {
382 this_len = sizeof(*dir_item) + 385 this_len = sizeof(*dir_item) +
@@ -429,3 +432,35 @@ int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans,
429 } 432 }
430 return ret; 433 return ret;
431} 434}
435
436int verify_dir_item(struct btrfs_root *root,
437 struct extent_buffer *leaf,
438 struct btrfs_dir_item *dir_item)
439{
440 u16 namelen = BTRFS_NAME_LEN;
441 u8 type = btrfs_dir_type(leaf, dir_item);
442
443 if (type >= BTRFS_FT_MAX) {
444 printk(KERN_CRIT "btrfs: invalid dir item type: %d\n",
445 (int)type);
446 return 1;
447 }
448
449 if (type == BTRFS_FT_XATTR)
450 namelen = XATTR_NAME_MAX;
451
452 if (btrfs_dir_name_len(leaf, dir_item) > namelen) {
453 printk(KERN_CRIT "btrfS: invalid dir item name len: %u\n",
454 (unsigned)btrfs_dir_data_len(leaf, dir_item));
455 return 1;
456 }
457
458 /* BTRFS_MAX_XATTR_SIZE is the same for all dir items */
459 if (btrfs_dir_data_len(leaf, dir_item) > BTRFS_MAX_XATTR_SIZE(root)) {
460 printk(KERN_CRIT "btrfs: invalid dir item data len: %u\n",
461 (unsigned)btrfs_dir_data_len(leaf, dir_item));
462 return 1;
463 }
464
465 return 0;
466}