bcachefs: Fix pool->alloc NULL pointer dereference

btree_interior_update_pool has not been initialized before the
filesystem becomes read-write, thus mempool_alloc in bch2_btree_update_start
will trigger pool->alloc NULL pointer dereference in mempool_alloc_noprof

Reported-by: syzbot+2f3859bd28f20fa682e6@syzkaller.appspotmail.com
Signed-off-by: Alan Huang <mmpgouride@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
Alan Huang 2025-06-15 13:41:22 +08:00 committed by Kent Overstreet
parent d89a34b14d
commit 56be92c63f
2 changed files with 24 additions and 8 deletions

View file

@ -767,7 +767,8 @@ struct btree_trans_buf {
x(sysfs) \
x(btree_write_buffer) \
x(btree_node_scrub) \
x(async_recovery_passes)
x(async_recovery_passes) \
x(ioctl_data)
enum bch_write_ref {
#define x(n) BCH_WRITE_REF_##n,

View file

@ -319,6 +319,7 @@ static int bch2_data_thread(void *arg)
ctx->stats.ret = BCH_IOCTL_DATA_EVENT_RET_done;
ctx->stats.data_type = (int) DATA_PROGRESS_DATA_TYPE_done;
}
enumerated_ref_put(&ctx->c->writes, BCH_WRITE_REF_ioctl_data);
return 0;
}
@ -378,15 +379,24 @@ static long bch2_ioctl_data(struct bch_fs *c,
struct bch_data_ctx *ctx;
int ret;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
if (!enumerated_ref_tryget(&c->writes, BCH_WRITE_REF_ioctl_data))
return -EROFS;
if (arg.op >= BCH_DATA_OP_NR || arg.flags)
return -EINVAL;
if (!capable(CAP_SYS_ADMIN)) {
ret = -EPERM;
goto put_ref;
}
if (arg.op >= BCH_DATA_OP_NR || arg.flags) {
ret = -EINVAL;
goto put_ref;
}
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return -ENOMEM;
if (!ctx) {
ret = -ENOMEM;
goto put_ref;
}
ctx->c = c;
ctx->arg = arg;
@ -395,7 +405,12 @@ static long bch2_ioctl_data(struct bch_fs *c,
&bcachefs_data_ops,
bch2_data_thread);
if (ret < 0)
kfree(ctx);
goto cleanup;
return ret;
cleanup:
kfree(ctx);
put_ref:
enumerated_ref_put(&c->writes, BCH_WRITE_REF_ioctl_data);
return ret;
}