mirror of
https://github.com/kdave/btrfs-progs
synced 2025-01-30 09:21:45 +00:00
btrfs-progs: check link_subvol name base
In principle, link_subvol() can be given an abitrary string as the name of the saved subvolume. It copies it into a fixed-size stack buffer and then uses it as dirent names without testing its length. This limits its length to BTRFS_NAME_LEN. This was found by static analsys. Signed-off-by: Zach Brown <zab@redhat.com> Signed-off-by: David Sterba <dsterba@suse.cz> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
This commit is contained in:
parent
69dc09a3ce
commit
538897923e
@ -1428,10 +1428,15 @@ static struct btrfs_root * link_subvol(struct btrfs_root *root,
|
||||
struct btrfs_key key;
|
||||
u64 dirid = btrfs_root_dirid(&root->root_item);
|
||||
u64 index = 2;
|
||||
char buf[64];
|
||||
char buf[BTRFS_NAME_LEN + 1]; /* for snprintf null */
|
||||
int len;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
len = strlen(base);
|
||||
if (len < 1 || len > BTRFS_NAME_LEN)
|
||||
return NULL;
|
||||
|
||||
path = btrfs_alloc_path();
|
||||
BUG_ON(!path);
|
||||
|
||||
@ -1467,18 +1472,22 @@ static struct btrfs_root * link_subvol(struct btrfs_root *root,
|
||||
key.offset = (u64)-1;
|
||||
key.type = BTRFS_ROOT_ITEM_KEY;
|
||||
|
||||
strcpy(buf, base);
|
||||
memcpy(buf, base, len);
|
||||
for (i = 0; i < 1024; i++) {
|
||||
ret = btrfs_insert_dir_item(trans, root, buf, strlen(buf),
|
||||
ret = btrfs_insert_dir_item(trans, root, buf, len,
|
||||
dirid, &key, BTRFS_FT_DIR, index);
|
||||
if (ret != -EEXIST)
|
||||
break;
|
||||
sprintf(buf, "%s%d", base, i);
|
||||
len = snprintf(buf, ARRAY_SIZE(buf), "%s%d", base, i);
|
||||
if (len < 1 || len > BTRFS_NAME_LEN) {
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
btrfs_set_inode_size(leaf, inode_item, strlen(buf) * 2 +
|
||||
btrfs_set_inode_size(leaf, inode_item, len * 2 +
|
||||
btrfs_inode_size(leaf, inode_item));
|
||||
btrfs_mark_buffer_dirty(leaf);
|
||||
btrfs_release_path(path);
|
||||
@ -1487,13 +1496,13 @@ static struct btrfs_root * link_subvol(struct btrfs_root *root,
|
||||
ret = btrfs_add_root_ref(trans, tree_root, root_objectid,
|
||||
BTRFS_ROOT_BACKREF_KEY,
|
||||
root->root_key.objectid,
|
||||
dirid, index, buf, strlen(buf));
|
||||
dirid, index, buf, len);
|
||||
BUG_ON(ret);
|
||||
|
||||
/* now add the forward ref */
|
||||
ret = btrfs_add_root_ref(trans, tree_root, root->root_key.objectid,
|
||||
BTRFS_ROOT_REF_KEY, root_objectid,
|
||||
dirid, index, buf, strlen(buf));
|
||||
dirid, index, buf, len);
|
||||
|
||||
ret = btrfs_commit_transaction(trans, root);
|
||||
BUG_ON(ret);
|
||||
|
Loading…
Reference in New Issue
Block a user