diff options
author | Xiubo Li <xiubli@redhat.com> | 2019-05-29 16:16:05 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2019-07-10 23:21:16 -0400 |
commit | 553768d1169a48c0cd87c4eb4ab57534ee663415 (patch) | |
tree | 0f08a0b21d2a773f3f400c0e725444f20f746dc5 /drivers/block | |
parent | b49773e7bcf316f238f6709ad9e1999dcc3ed433 (diff) |
nbd: fix crash when the blksize is zero
This will allow the blksize to be set zero and then use 1024 as
default.
Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Xiubo Li <xiubli@redhat.com>
[fix to use goto out instead of return in genl_connect]
Signed-off-by: Mike Christie <mchristi@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/nbd.c | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 3a9bca3aa093..5c4e3f2160bf 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c | |||
@@ -134,6 +134,8 @@ static struct dentry *nbd_dbg_dir; | |||
134 | 134 | ||
135 | #define NBD_MAGIC 0x68797548 | 135 | #define NBD_MAGIC 0x68797548 |
136 | 136 | ||
137 | #define NBD_DEF_BLKSIZE 1024 | ||
138 | |||
137 | static unsigned int nbds_max = 16; | 139 | static unsigned int nbds_max = 16; |
138 | static int max_part = 16; | 140 | static int max_part = 16; |
139 | static struct workqueue_struct *recv_workqueue; | 141 | static struct workqueue_struct *recv_workqueue; |
@@ -1236,6 +1238,14 @@ static void nbd_clear_sock_ioctl(struct nbd_device *nbd, | |||
1236 | nbd_config_put(nbd); | 1238 | nbd_config_put(nbd); |
1237 | } | 1239 | } |
1238 | 1240 | ||
1241 | static bool nbd_is_valid_blksize(unsigned long blksize) | ||
1242 | { | ||
1243 | if (!blksize || !is_power_of_2(blksize) || blksize < 512 || | ||
1244 | blksize > PAGE_SIZE) | ||
1245 | return false; | ||
1246 | return true; | ||
1247 | } | ||
1248 | |||
1239 | /* Must be called with config_lock held */ | 1249 | /* Must be called with config_lock held */ |
1240 | static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd, | 1250 | static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd, |
1241 | unsigned int cmd, unsigned long arg) | 1251 | unsigned int cmd, unsigned long arg) |
@@ -1251,8 +1261,9 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd, | |||
1251 | case NBD_SET_SOCK: | 1261 | case NBD_SET_SOCK: |
1252 | return nbd_add_socket(nbd, arg, false); | 1262 | return nbd_add_socket(nbd, arg, false); |
1253 | case NBD_SET_BLKSIZE: | 1263 | case NBD_SET_BLKSIZE: |
1254 | if (!arg || !is_power_of_2(arg) || arg < 512 || | 1264 | if (!arg) |
1255 | arg > PAGE_SIZE) | 1265 | arg = NBD_DEF_BLKSIZE; |
1266 | if (!nbd_is_valid_blksize(arg)) | ||
1256 | return -EINVAL; | 1267 | return -EINVAL; |
1257 | nbd_size_set(nbd, arg, | 1268 | nbd_size_set(nbd, arg, |
1258 | div_s64(config->bytesize, arg)); | 1269 | div_s64(config->bytesize, arg)); |
@@ -1332,7 +1343,7 @@ static struct nbd_config *nbd_alloc_config(void) | |||
1332 | atomic_set(&config->recv_threads, 0); | 1343 | atomic_set(&config->recv_threads, 0); |
1333 | init_waitqueue_head(&config->recv_wq); | 1344 | init_waitqueue_head(&config->recv_wq); |
1334 | init_waitqueue_head(&config->conn_wait); | 1345 | init_waitqueue_head(&config->conn_wait); |
1335 | config->blksize = 1024; | 1346 | config->blksize = NBD_DEF_BLKSIZE; |
1336 | atomic_set(&config->live_connections, 0); | 1347 | atomic_set(&config->live_connections, 0); |
1337 | try_module_get(THIS_MODULE); | 1348 | try_module_get(THIS_MODULE); |
1338 | return config; | 1349 | return config; |
@@ -1768,6 +1779,12 @@ again: | |||
1768 | if (info->attrs[NBD_ATTR_BLOCK_SIZE_BYTES]) { | 1779 | if (info->attrs[NBD_ATTR_BLOCK_SIZE_BYTES]) { |
1769 | u64 bsize = | 1780 | u64 bsize = |
1770 | nla_get_u64(info->attrs[NBD_ATTR_BLOCK_SIZE_BYTES]); | 1781 | nla_get_u64(info->attrs[NBD_ATTR_BLOCK_SIZE_BYTES]); |
1782 | if (!bsize) | ||
1783 | bsize = NBD_DEF_BLKSIZE; | ||
1784 | if (!nbd_is_valid_blksize(bsize)) { | ||
1785 | ret = -EINVAL; | ||
1786 | goto out; | ||
1787 | } | ||
1771 | nbd_size_set(nbd, bsize, div64_u64(config->bytesize, bsize)); | 1788 | nbd_size_set(nbd, bsize, div64_u64(config->bytesize, bsize)); |
1772 | } | 1789 | } |
1773 | if (info->attrs[NBD_ATTR_TIMEOUT]) { | 1790 | if (info->attrs[NBD_ATTR_TIMEOUT]) { |