end = range.start + range.len; If the range.start/range.len is a very large value, then end can overflow in this operation. It results into a crash in get_valid_blocks() when accessing the invalid range.start segno. This issue is reported in ioctl fuzz testing.
Unified · Split
| @@ -2264,9 +2264,9 @@ static int f2fs_ioc_gc_range(struct file *filp, unsigned long arg) · 2263 unmodified lines | |||
| 2264 | return -EROFS; | 2264 | return -EROFS; |
| 2265 | 2265 | ||
| 2266 | end = range.start + range.len; | 2266 | end = range.start + range.len; |
| 2267 | if (range.start < MAIN_BLKADDR(sbi) || end >= MAX_BLKADDR(sbi)) { | 2267 | if (end < range.start || range.start < MAIN_BLKADDR(sbi) || |
| 2268 | end >= MAX_BLKADDR(sbi)) | ||
| 2268 | return -EINVAL; | 2269 | return -EINVAL; |
| 2269 | } | ||
| 2270 | 2270 | ||
| 2271 | ret = mnt_want_write_file(filp); | 2271 | ret = mnt_want_write_file(filp); |
| 2272 | if (ret) | 2272 | if (ret) |