Commit c688982f authored by Xiubo Li's avatar Xiubo Li Committed by Greg Kroah-Hartman

nbd: fix crash when the blksize is zero

[ Upstream commit 553768d1 ]

This will allow the blksize to be set zero and then use 1024 as
default.
Reviewed-by: default avatarJosef Bacik <josef@toxicpanda.com>
Signed-off-by: default avatarXiubo Li <xiubli@redhat.com>
[fix to use goto out instead of return in genl_connect]
Signed-off-by: default avatarMike Christie <mchristi@redhat.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 63bb8b76
......@@ -133,6 +133,8 @@ static struct dentry *nbd_dbg_dir;
#define NBD_MAGIC 0x68797548
#define NBD_DEF_BLKSIZE 1024
static unsigned int nbds_max = 16;
static int max_part = 16;
static int part_shift;
......@@ -1241,6 +1243,14 @@ static void nbd_clear_sock_ioctl(struct nbd_device *nbd,
nbd_config_put(nbd);
}
static bool nbd_is_valid_blksize(unsigned long blksize)
{
if (!blksize || !is_power_of_2(blksize) || blksize < 512 ||
blksize > PAGE_SIZE)
return false;
return true;
}
/* Must be called with config_lock held */
static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
unsigned int cmd, unsigned long arg)
......@@ -1256,8 +1266,9 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
case NBD_SET_SOCK:
return nbd_add_socket(nbd, arg, false);
case NBD_SET_BLKSIZE:
if (!arg || !is_power_of_2(arg) || arg < 512 ||
arg > PAGE_SIZE)
if (!arg)
arg = NBD_DEF_BLKSIZE;
if (!nbd_is_valid_blksize(arg))
return -EINVAL;
nbd_size_set(nbd, arg,
div_s64(config->bytesize, arg));
......@@ -1337,7 +1348,7 @@ static struct nbd_config *nbd_alloc_config(void)
atomic_set(&config->recv_threads, 0);
init_waitqueue_head(&config->recv_wq);
init_waitqueue_head(&config->conn_wait);
config->blksize = 1024;
config->blksize = NBD_DEF_BLKSIZE;
atomic_set(&config->live_connections, 0);
try_module_get(THIS_MODULE);
return config;
......@@ -1773,6 +1784,12 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info)
if (info->attrs[NBD_ATTR_BLOCK_SIZE_BYTES]) {
u64 bsize =
nla_get_u64(info->attrs[NBD_ATTR_BLOCK_SIZE_BYTES]);
if (!bsize)
bsize = NBD_DEF_BLKSIZE;
if (!nbd_is_valid_blksize(bsize)) {
ret = -EINVAL;
goto out;
}
nbd_size_set(nbd, bsize, div64_u64(config->bytesize, bsize));
}
if (info->attrs[NBD_ATTR_TIMEOUT]) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment