Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 243155
b: refs/heads/master
c: 22a94d4
h: refs/heads/master
i:
  243153: d72d0a8
  243151: e1e98f0
v: v3
  • Loading branch information
Josef Bacik committed Mar 17, 2011
1 parent 0688448 commit ad90b21
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 41415730a1050499fbd63b3f7dd59b3a4c3bb91a
refs/heads/master: 22a94d44bd6876a90630338229da6c0436d46593
3 changes: 3 additions & 0 deletions trunk/fs/btrfs/ctree.h
Original file line number Diff line number Diff line change
Expand Up @@ -2393,6 +2393,9 @@ struct btrfs_dir_item *btrfs_lookup_xattr(struct btrfs_trans_handle *trans,
struct btrfs_path *path, u64 dir,
const char *name, u16 name_len,
int mod);
int verify_dir_item(struct btrfs_root *root,
struct extent_buffer *leaf,
struct btrfs_dir_item *dir_item);

/* orphan.c */
int btrfs_insert_orphan_item(struct btrfs_trans_handle *trans,
Expand Down
35 changes: 35 additions & 0 deletions trunk/fs/btrfs/dir-item.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,9 @@ struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root,

leaf = path->nodes[0];
dir_item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_dir_item);
if (verify_dir_item(root, leaf, dir_item))
return NULL;

total_len = btrfs_item_size_nr(leaf, path->slots[0]);
while (cur < total_len) {
this_len = sizeof(*dir_item) +
Expand Down Expand Up @@ -429,3 +432,35 @@ int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans,
}
return ret;
}

int verify_dir_item(struct btrfs_root *root,
struct extent_buffer *leaf,
struct btrfs_dir_item *dir_item)
{
u16 namelen = BTRFS_NAME_LEN;
u8 type = btrfs_dir_type(leaf, dir_item);

if (type >= BTRFS_FT_MAX) {
printk(KERN_CRIT "btrfs: invalid dir item type: %d\n",
(int)type);
return 1;
}

if (type == BTRFS_FT_XATTR)
namelen = XATTR_NAME_MAX;

if (btrfs_dir_name_len(leaf, dir_item) > namelen) {
printk(KERN_CRIT "btrfS: invalid dir item name len: %u\n",
(unsigned)btrfs_dir_data_len(leaf, dir_item));
return 1;
}

/* BTRFS_MAX_XATTR_SIZE is the same for all dir items */
if (btrfs_dir_data_len(leaf, dir_item) > BTRFS_MAX_XATTR_SIZE(root)) {
printk(KERN_CRIT "btrfs: invalid dir item data len: %u\n",
(unsigned)btrfs_dir_data_len(leaf, dir_item));
return 1;
}

return 0;
}
3 changes: 3 additions & 0 deletions trunk/fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -4272,6 +4272,9 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
while (di_cur < di_total) {
struct btrfs_key location;

if (verify_dir_item(root, leaf, di))
break;

name_len = btrfs_dir_name_len(leaf, di);
if (name_len <= sizeof(tmp_name)) {
name_ptr = tmp_name;
Expand Down
7 changes: 7 additions & 0 deletions trunk/fs/btrfs/tree-log.c
Original file line number Diff line number Diff line change
Expand Up @@ -1286,6 +1286,8 @@ static noinline int replay_one_dir_item(struct btrfs_trans_handle *trans,
ptr_end = ptr + item_size;
while (ptr < ptr_end) {
di = (struct btrfs_dir_item *)ptr;
if (verify_dir_item(root, eb, di))
return -EIO;
name_len = btrfs_dir_name_len(eb, di);
ret = replay_one_name(trans, root, path, eb, di, key);
BUG_ON(ret);
Expand Down Expand Up @@ -1412,6 +1414,11 @@ static noinline int check_item_in_log(struct btrfs_trans_handle *trans,
ptr_end = ptr + item_size;
while (ptr < ptr_end) {
di = (struct btrfs_dir_item *)ptr;
if (verify_dir_item(root, eb, di)) {
ret = -EIO;
goto out;
}

name_len = btrfs_dir_name_len(eb, di);
name = kmalloc(name_len, GFP_NOFS);
if (!name) {
Expand Down
2 changes: 2 additions & 0 deletions trunk/fs/btrfs/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,8 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
break;

di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
if (verify_dir_item(root, leaf, di))
continue;

name_len = btrfs_dir_name_len(leaf, di);
total_size += name_len + 1;
Expand Down

0 comments on commit ad90b21

Please sign in to comment.