Skip to content

Commit 697ba0b

Browse files
Alexey Dobriyanaxboe
authored andcommitted
block: fix integer overflow in BLKSECDISCARD
I independently rediscovered commit 22d24a5 block: fix overflow in blk_ioctl_discard() but for secure erase. Same problem: uint64_t r[2] = {512, 18446744073709551104ULL}; ioctl(fd, BLKSECDISCARD, r); will enter near infinite loop inside blkdev_issue_secure_erase(): a.out: attempt to access beyond end of device loop0: rw=5, sector=3399043073, nr_sectors = 1024 limit=2048 bio_check_eod: 3286214 callbacks suppressed Signed-off-by: Alexey Dobriyan <[email protected]> Link: https://lore.kernel.org/r/9e64057f-650a-46d1-b9f7-34af391536ef@p183 Signed-off-by: Jens Axboe <[email protected]>
1 parent 2be6190 commit 697ba0b

File tree

1 file changed

+5
-4
lines changed

1 file changed

+5
-4
lines changed

block/ioctl.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ static int blk_ioctl_discard(struct block_device *bdev, blk_mode_t mode,
126126
return -EINVAL;
127127

128128
filemap_invalidate_lock(bdev->bd_mapping);
129-
err = truncate_bdev_range(bdev, mode, start, start + len - 1);
129+
err = truncate_bdev_range(bdev, mode, start, end - 1);
130130
if (err)
131131
goto fail;
132132

@@ -163,7 +163,7 @@ static int blk_ioctl_discard(struct block_device *bdev, blk_mode_t mode,
163163
static int blk_ioctl_secure_erase(struct block_device *bdev, blk_mode_t mode,
164164
void __user *argp)
165165
{
166-
uint64_t start, len;
166+
uint64_t start, len, end;
167167
uint64_t range[2];
168168
int err;
169169

@@ -178,11 +178,12 @@ static int blk_ioctl_secure_erase(struct block_device *bdev, blk_mode_t mode,
178178
len = range[1];
179179
if ((start & 511) || (len & 511))
180180
return -EINVAL;
181-
if (start + len > bdev_nr_bytes(bdev))
181+
if (check_add_overflow(start, len, &end) ||
182+
end > bdev_nr_bytes(bdev))
182183
return -EINVAL;
183184

184185
filemap_invalidate_lock(bdev->bd_mapping);
185-
err = truncate_bdev_range(bdev, mode, start, start + len - 1);
186+
err = truncate_bdev_range(bdev, mode, start, end - 1);
186187
if (!err)
187188
err = blkdev_issue_secure_erase(bdev, start >> 9, len >> 9,
188189
GFP_KERNEL);

0 commit comments

Comments
 (0)