Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ublk: fix NULL pointer dereference in ublk_ctrl_set_size()

ublk_ctrl_set_size() unconditionally dereferences ub->ub_disk via
set_capacity_and_notify() without checking if it is NULL.

ub->ub_disk is NULL before UBLK_CMD_START_DEV completes (it is only
assigned in ublk_ctrl_start_dev()) and after UBLK_CMD_STOP_DEV runs
(ublk_detach_disk() sets it to NULL). Since the UBLK_CMD_UPDATE_SIZE
handler performs no state validation, a user can trigger a NULL pointer
dereference by sending UPDATE_SIZE to a device that has been added but
not yet started, or one that has been stopped.

Fix this by checking ub->ub_disk under ub->mutex before dereferencing
it, and returning -ENODEV if the disk is not available.

Fixes: 98b995660bff ("ublk: Add UBLK_U_CMD_UPDATE_SIZE")
Cc: stable@vger.kernel.org
Signed-off-by: Mehul Rao <mehulrao@gmail.com>
Reviewed-by: Ming Lei <ming.lei@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Mehul Rao and committed by
Jens Axboe
25966fc0 ce8ee858

+9 -3
+9 -3
drivers/block/ublk_drv.c
··· 5003 5003 return 0; 5004 5004 } 5005 5005 5006 - static void ublk_ctrl_set_size(struct ublk_device *ub, const struct ublksrv_ctrl_cmd *header) 5006 + static int ublk_ctrl_set_size(struct ublk_device *ub, const struct ublksrv_ctrl_cmd *header) 5007 5007 { 5008 5008 struct ublk_param_basic *p = &ub->params.basic; 5009 5009 u64 new_size = header->data[0]; 5010 + int ret = 0; 5010 5011 5011 5012 mutex_lock(&ub->mutex); 5013 + if (!ub->ub_disk) { 5014 + ret = -ENODEV; 5015 + goto out; 5016 + } 5012 5017 p->dev_sectors = new_size; 5013 5018 set_capacity_and_notify(ub->ub_disk, p->dev_sectors); 5019 + out: 5014 5020 mutex_unlock(&ub->mutex); 5021 + return ret; 5015 5022 } 5016 5023 5017 5024 struct count_busy { ··· 5338 5331 ret = ublk_ctrl_end_recovery(ub, &header); 5339 5332 break; 5340 5333 case UBLK_CMD_UPDATE_SIZE: 5341 - ublk_ctrl_set_size(ub, &header); 5342 - ret = 0; 5334 + ret = ublk_ctrl_set_size(ub, &header); 5343 5335 break; 5344 5336 case UBLK_CMD_QUIESCE_DEV: 5345 5337 ret = ublk_ctrl_quiesce_dev(ub, &header);