mirror of
https://github.com/koverstreet/bcachefs-tools.git
synced 2025-02-23 00:00:02 +03:00
Update bcachefs sources to ae6f512de8 bcachefs: Fix out of bounds read in fs usage ioctl
This commit is contained in:
parent
bf14597460
commit
a76f36fc6e
@ -1 +1 @@
|
|||||||
b6d54265513ceb7532e3983163338c1ad28a0284
|
ae6f512de8cdd129ce873e14eab84b8e0746daed
|
||||||
|
@ -436,7 +436,7 @@ static int bch2_check_fix_ptrs(struct bch_fs *c, enum btree_id btree_id,
|
|||||||
p.ptr.dev, PTR_BUCKET_NR(ca, &p.ptr),
|
p.ptr.dev, PTR_BUCKET_NR(ca, &p.ptr),
|
||||||
bch2_data_types[ptr_data_type(k->k, &p.ptr)],
|
bch2_data_types[ptr_data_type(k->k, &p.ptr)],
|
||||||
p.ptr.gen)) {
|
p.ptr.gen)) {
|
||||||
if (p.ptr.cached) {
|
if (!p.ptr.cached) {
|
||||||
g2->_mark.gen = g->_mark.gen = p.ptr.gen;
|
g2->_mark.gen = g->_mark.gen = p.ptr.gen;
|
||||||
g2->gen_valid = g->gen_valid = true;
|
g2->gen_valid = g->gen_valid = true;
|
||||||
set_bit(BCH_FS_NEED_ALLOC_WRITE, &c->flags);
|
set_bit(BCH_FS_NEED_ALLOC_WRITE, &c->flags);
|
||||||
@ -450,7 +450,7 @@ static int bch2_check_fix_ptrs(struct bch_fs *c, enum btree_id btree_id,
|
|||||||
p.ptr.dev, PTR_BUCKET_NR(ca, &p.ptr),
|
p.ptr.dev, PTR_BUCKET_NR(ca, &p.ptr),
|
||||||
bch2_data_types[ptr_data_type(k->k, &p.ptr)],
|
bch2_data_types[ptr_data_type(k->k, &p.ptr)],
|
||||||
p.ptr.gen, g->mark.gen)) {
|
p.ptr.gen, g->mark.gen)) {
|
||||||
if (p.ptr.cached) {
|
if (!p.ptr.cached) {
|
||||||
g2->_mark.gen = g->_mark.gen = p.ptr.gen;
|
g2->_mark.gen = g->_mark.gen = p.ptr.gen;
|
||||||
g2->gen_valid = g->gen_valid = true;
|
g2->gen_valid = g->gen_valid = true;
|
||||||
g2->_mark.data_type = 0;
|
g2->_mark.data_type = 0;
|
||||||
|
@ -414,7 +414,8 @@ static long bch2_ioctl_fs_usage(struct bch_fs *c,
|
|||||||
struct bch_replicas_entry *src_e =
|
struct bch_replicas_entry *src_e =
|
||||||
cpu_replicas_entry(&c->replicas, i);
|
cpu_replicas_entry(&c->replicas, i);
|
||||||
|
|
||||||
if (replicas_usage_next(dst_e) > dst_end) {
|
/* check that we have enough space for one replicas entry */
|
||||||
|
if (dst_e + 1 > dst_end) {
|
||||||
ret = -ERANGE;
|
ret = -ERANGE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -523,7 +524,7 @@ static long bch2_ioctl_read_super(struct bch_fs *c,
|
|||||||
ret = copy_to_user((void __user *)(unsigned long)arg.sb,
|
ret = copy_to_user((void __user *)(unsigned long)arg.sb,
|
||||||
sb, vstruct_bytes(sb));
|
sb, vstruct_bytes(sb));
|
||||||
err:
|
err:
|
||||||
if (ca)
|
if (!IS_ERR_OR_NULL(ca))
|
||||||
percpu_ref_put(&ca->ref);
|
percpu_ref_put(&ca->ref);
|
||||||
mutex_unlock(&c->sb_lock);
|
mutex_unlock(&c->sb_lock);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include <linux/posix_acl.h>
|
#include <linux/posix_acl.h>
|
||||||
#include <linux/random.h>
|
#include <linux/random.h>
|
||||||
#include <linux/statfs.h>
|
#include <linux/statfs.h>
|
||||||
|
#include <linux/string.h>
|
||||||
#include <linux/xattr.h>
|
#include <linux/xattr.h>
|
||||||
|
|
||||||
static struct kmem_cache *bch2_inode_cache;
|
static struct kmem_cache *bch2_inode_cache;
|
||||||
@ -1311,6 +1312,9 @@ static char **split_devs(const char *_dev_name, unsigned *nr)
|
|||||||
char *dev_name = NULL, **devs = NULL, *s;
|
char *dev_name = NULL, **devs = NULL, *s;
|
||||||
size_t i, nr_devs = 0;
|
size_t i, nr_devs = 0;
|
||||||
|
|
||||||
|
if (strlen(_dev_name) == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
dev_name = kstrdup(_dev_name, GFP_KERNEL);
|
dev_name = kstrdup(_dev_name, GFP_KERNEL);
|
||||||
if (!dev_name)
|
if (!dev_name)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -512,7 +512,9 @@ static int check_inodes(struct bch_fs *c, bool full)
|
|||||||
|
|
||||||
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
|
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
|
||||||
|
|
||||||
for_each_btree_key(&trans, iter, BTREE_ID_inodes, POS_MIN, 0, k, ret) {
|
for_each_btree_key(&trans, iter, BTREE_ID_inodes, POS_MIN,
|
||||||
|
BTREE_ITER_INTENT|
|
||||||
|
BTREE_ITER_PREFETCH, k, ret) {
|
||||||
if (k.k->type != KEY_TYPE_inode)
|
if (k.k->type != KEY_TYPE_inode)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -621,7 +623,8 @@ static int check_extents(struct bch_fs *c)
|
|||||||
|
|
||||||
iter = bch2_trans_get_iter(&trans, BTREE_ID_extents,
|
iter = bch2_trans_get_iter(&trans, BTREE_ID_extents,
|
||||||
POS(BCACHEFS_ROOT_INO, 0),
|
POS(BCACHEFS_ROOT_INO, 0),
|
||||||
BTREE_ITER_INTENT);
|
BTREE_ITER_INTENT|
|
||||||
|
BTREE_ITER_PREFETCH);
|
||||||
retry:
|
retry:
|
||||||
while ((k = bch2_btree_iter_peek(iter)).k &&
|
while ((k = bch2_btree_iter_peek(iter)).k &&
|
||||||
!(ret = bkey_err(k))) {
|
!(ret = bkey_err(k))) {
|
||||||
@ -719,7 +722,9 @@ static int check_dirents(struct bch_fs *c)
|
|||||||
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
|
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
|
||||||
|
|
||||||
iter = bch2_trans_get_iter(&trans, BTREE_ID_dirents,
|
iter = bch2_trans_get_iter(&trans, BTREE_ID_dirents,
|
||||||
POS(BCACHEFS_ROOT_INO, 0), 0);
|
POS(BCACHEFS_ROOT_INO, 0),
|
||||||
|
BTREE_ITER_INTENT|
|
||||||
|
BTREE_ITER_PREFETCH);
|
||||||
retry:
|
retry:
|
||||||
while ((k = bch2_btree_iter_peek(iter)).k &&
|
while ((k = bch2_btree_iter_peek(iter)).k &&
|
||||||
!(ret = bkey_err(k))) {
|
!(ret = bkey_err(k))) {
|
||||||
@ -920,7 +925,9 @@ static int check_xattrs(struct bch_fs *c)
|
|||||||
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
|
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
|
||||||
|
|
||||||
iter = bch2_trans_get_iter(&trans, BTREE_ID_xattrs,
|
iter = bch2_trans_get_iter(&trans, BTREE_ID_xattrs,
|
||||||
POS(BCACHEFS_ROOT_INO, 0), 0);
|
POS(BCACHEFS_ROOT_INO, 0),
|
||||||
|
BTREE_ITER_INTENT|
|
||||||
|
BTREE_ITER_PREFETCH);
|
||||||
retry:
|
retry:
|
||||||
while ((k = bch2_btree_iter_peek(iter)).k &&
|
while ((k = bch2_btree_iter_peek(iter)).k &&
|
||||||
!(ret = bkey_err(k))) {
|
!(ret = bkey_err(k))) {
|
||||||
@ -1108,7 +1115,9 @@ static int check_directory_structure(struct bch_fs *c)
|
|||||||
|
|
||||||
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
|
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
|
||||||
|
|
||||||
for_each_btree_key(&trans, iter, BTREE_ID_inodes, POS_MIN, 0, k, ret) {
|
for_each_btree_key(&trans, iter, BTREE_ID_inodes, POS_MIN,
|
||||||
|
BTREE_ITER_INTENT|
|
||||||
|
BTREE_ITER_PREFETCH, k, ret) {
|
||||||
if (k.k->type != KEY_TYPE_inode)
|
if (k.k->type != KEY_TYPE_inode)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -1207,7 +1216,9 @@ static int check_nlinks_find_hardlinks(struct bch_fs *c,
|
|||||||
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
|
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
|
||||||
|
|
||||||
for_each_btree_key(&trans, iter, BTREE_ID_inodes,
|
for_each_btree_key(&trans, iter, BTREE_ID_inodes,
|
||||||
POS(0, start), 0, k, ret) {
|
POS(0, start),
|
||||||
|
BTREE_ITER_INTENT|
|
||||||
|
BTREE_ITER_PREFETCH, k, ret) {
|
||||||
if (k.k->type != KEY_TYPE_inode)
|
if (k.k->type != KEY_TYPE_inode)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -1255,7 +1266,9 @@ static int check_nlinks_walk_dirents(struct bch_fs *c, struct nlink_table *links
|
|||||||
|
|
||||||
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
|
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
|
||||||
|
|
||||||
for_each_btree_key(&trans, iter, BTREE_ID_dirents, POS_MIN, 0, k, ret) {
|
for_each_btree_key(&trans, iter, BTREE_ID_dirents, POS_MIN,
|
||||||
|
BTREE_ITER_INTENT|
|
||||||
|
BTREE_ITER_PREFETCH, k, ret) {
|
||||||
switch (k.k->type) {
|
switch (k.k->type) {
|
||||||
case KEY_TYPE_dirent:
|
case KEY_TYPE_dirent:
|
||||||
d = bkey_s_c_to_dirent(k);
|
d = bkey_s_c_to_dirent(k);
|
||||||
@ -1293,7 +1306,9 @@ static int check_nlinks_update_hardlinks(struct bch_fs *c,
|
|||||||
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
|
bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0);
|
||||||
|
|
||||||
for_each_btree_key(&trans, iter, BTREE_ID_inodes,
|
for_each_btree_key(&trans, iter, BTREE_ID_inodes,
|
||||||
POS(0, range_start), 0, k, ret) {
|
POS(0, range_start),
|
||||||
|
BTREE_ITER_INTENT|
|
||||||
|
BTREE_ITER_PREFETCH, k, ret) {
|
||||||
if (k.k->p.offset >= range_end)
|
if (k.k->p.offset >= range_end)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -315,11 +315,20 @@ int bch2_opts_check_may_set(struct bch_fs *c)
|
|||||||
int bch2_parse_mount_opts(struct bch_fs *c, struct bch_opts *opts,
|
int bch2_parse_mount_opts(struct bch_fs *c, struct bch_opts *opts,
|
||||||
char *options)
|
char *options)
|
||||||
{
|
{
|
||||||
|
char *copied_opts, *copied_opts_start;
|
||||||
char *opt, *name, *val;
|
char *opt, *name, *val;
|
||||||
int ret, id;
|
int ret, id;
|
||||||
u64 v;
|
u64 v;
|
||||||
|
|
||||||
while ((opt = strsep(&options, ",")) != NULL) {
|
if (!options)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
copied_opts = kstrdup(options, GFP_KERNEL);
|
||||||
|
if (!copied_opts)
|
||||||
|
return -1;
|
||||||
|
copied_opts_start = copied_opts;
|
||||||
|
|
||||||
|
while ((opt = strsep(&copied_opts, ",")) != NULL) {
|
||||||
name = strsep(&opt, "=");
|
name = strsep(&opt, "=");
|
||||||
val = opt;
|
val = opt;
|
||||||
|
|
||||||
@ -363,16 +372,24 @@ int bch2_parse_mount_opts(struct bch_fs *c, struct bch_opts *opts,
|
|||||||
bch2_opt_set_by_id(opts, id, v);
|
bch2_opt_set_by_id(opts, id, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
ret = 0;
|
||||||
|
goto out;
|
||||||
|
|
||||||
bad_opt:
|
bad_opt:
|
||||||
pr_err("Bad mount option %s", name);
|
pr_err("Bad mount option %s", name);
|
||||||
return -1;
|
ret = -1;
|
||||||
|
goto out;
|
||||||
bad_val:
|
bad_val:
|
||||||
pr_err("Invalid value %s for mount option %s", val, name);
|
pr_err("Invalid value %s for mount option %s", val, name);
|
||||||
return -1;
|
ret = -1;
|
||||||
|
goto out;
|
||||||
no_val:
|
no_val:
|
||||||
pr_err("Mount option %s requires a value", name);
|
pr_err("Mount option %s requires a value", name);
|
||||||
return -1;
|
ret = -1;
|
||||||
|
goto out;
|
||||||
|
out:
|
||||||
|
kfree(copied_opts_start);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* io opts: */
|
/* io opts: */
|
||||||
|
@ -110,7 +110,7 @@ struct bch_fs *bch2_dev_to_fs(dev_t dev)
|
|||||||
|
|
||||||
list_for_each_entry(c, &bch_fs_list, list)
|
list_for_each_entry(c, &bch_fs_list, list)
|
||||||
for_each_member_device_rcu(ca, c, i, NULL)
|
for_each_member_device_rcu(ca, c, i, NULL)
|
||||||
if (ca->disk_sb.bdev->bd_dev == dev) {
|
if (ca->disk_sb.bdev && ca->disk_sb.bdev->bd_dev == dev) {
|
||||||
closure_get(&c->cl);
|
closure_get(&c->cl);
|
||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user