mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-12-27 10:01:39 -05:00
mtdchar: fix integer overflow in read/write ioctls
The "req.start" and "req.len" variables are u64 values that come from the user at the start of the function. We mask away the high 32 bits of "req.len" so that's capped at U32_MAX but the "req.start" variable can go up to U64_MAX which means that the addition can still integer overflow. Use check_add_overflow() to fix this bug. Fixes:095bb6e44e("mtdchar: add MEMREAD ioctl") Fixes:6420ac0af9("mtdchar: prevent unbounded allocation in MEMWRITE ioctl") Cc: stable@vger.kernel.org Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
This commit is contained in:
committed by
Miquel Raynal
parent
3a86608788
commit
e4185bed73
@@ -599,6 +599,7 @@ mtdchar_write_ioctl(struct mtd_info *mtd, struct mtd_write_req __user *argp)
|
||||
uint8_t *datbuf = NULL, *oobbuf = NULL;
|
||||
size_t datbuf_len, oobbuf_len;
|
||||
int ret = 0;
|
||||
u64 end;
|
||||
|
||||
if (copy_from_user(&req, argp, sizeof(req)))
|
||||
return -EFAULT;
|
||||
@@ -618,7 +619,7 @@ mtdchar_write_ioctl(struct mtd_info *mtd, struct mtd_write_req __user *argp)
|
||||
req.len &= 0xffffffff;
|
||||
req.ooblen &= 0xffffffff;
|
||||
|
||||
if (req.start + req.len > mtd->size)
|
||||
if (check_add_overflow(req.start, req.len, &end) || end > mtd->size)
|
||||
return -EINVAL;
|
||||
|
||||
datbuf_len = min_t(size_t, req.len, mtd->erasesize);
|
||||
@@ -698,6 +699,7 @@ mtdchar_read_ioctl(struct mtd_info *mtd, struct mtd_read_req __user *argp)
|
||||
size_t datbuf_len, oobbuf_len;
|
||||
size_t orig_len, orig_ooblen;
|
||||
int ret = 0;
|
||||
u64 end;
|
||||
|
||||
if (copy_from_user(&req, argp, sizeof(req)))
|
||||
return -EFAULT;
|
||||
@@ -724,7 +726,7 @@ mtdchar_read_ioctl(struct mtd_info *mtd, struct mtd_read_req __user *argp)
|
||||
req.len &= 0xffffffff;
|
||||
req.ooblen &= 0xffffffff;
|
||||
|
||||
if (req.start + req.len > mtd->size) {
|
||||
if (check_add_overflow(req.start, req.len, &end) || end > mtd->size) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user