summaryrefslogtreecommitdiff
path: root/drivers/block
diff options
context:
space:
mode:
authorZhong Jinghua <zhongjinghua@huawei.com>2024-03-07 12:14:11 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-04-13 12:51:30 +0200
commit861021710bba9dfa0749a3c209a6c1773208b1f1 (patch)
tree2c78862478b17d92fd47a183de22dba8ef66f90d /drivers/block
parentb40877b8562c5720d0a7fce20729f56b75a3dede (diff)
downloadlinux-861021710bba9dfa0749a3c209a6c1773208b1f1.tar.gz
linux-861021710bba9dfa0749a3c209a6c1773208b1f1.tar.bz2
linux-861021710bba9dfa0749a3c209a6c1773208b1f1.zip
loop: loop_set_status_from_info() check before assignment
[ Upstream commit 9f6ad5d533d1c71e51bdd06a5712c4fbc8768dfa ] In loop_set_status_from_info(), lo->lo_offset and lo->lo_sizelimit should be checked before reassignment, because if an overflow error occurs, the original correct value will be changed to the wrong value, and it will not be changed back. More, the original patch did not solve the problem, the value was set and ioctl returned an error, but the subsequent io used the value in the loop driver, which still caused an alarm: loop_handle_cmd do_req_filebacked loff_t pos = ((loff_t) blk_rq_pos(rq) << 9) + lo->lo_offset; lo_rw_aio cmd->iocb.ki_pos = pos Fixes: c490a0b5a4f3 ("loop: Check for overflow while configuring loop") Signed-off-by: Zhong Jinghua <zhongjinghua@huawei.com> Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com> Link: https://lore.kernel.org/r/20230221095027.3656193-1-zhongjinghua@huaweicloud.com Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Genjian Zhang <zhanggenjian@kylinos.cn> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/loop.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index c999eef4e345..ff452c02b61f 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1296,13 +1296,13 @@ loop_set_status_from_info(struct loop_device *lo,
if (err)
return err;
+ /* Avoid assigning overflow values */
+ if (info->lo_offset > LLONG_MAX || info->lo_sizelimit > LLONG_MAX)
+ return -EOVERFLOW;
+
lo->lo_offset = info->lo_offset;
lo->lo_sizelimit = info->lo_sizelimit;
- /* loff_t vars have been assigned __u64 */
- if (lo->lo_offset < 0 || lo->lo_sizelimit < 0)
- return -EOVERFLOW;
-
memcpy(lo->lo_file_name, info->lo_file_name, LO_NAME_SIZE);
memcpy(lo->lo_crypt_name, info->lo_crypt_name, LO_NAME_SIZE);
lo->lo_file_name[LO_NAME_SIZE-1] = 0;