| From: Phillip Lougher <phillip@squashfs.org.uk> |
| Subject: Squashfs: fix variable overflow triggered by sysbot |
| Date: Mon, 13 Nov 2023 16:09:01 +0000 |
| |
| Sysbot reports a slab out of bounds write in squashfs_readahead(). |
| |
| This is ultimately caused by a file reporting an (infeasibly) large file |
| size (1407374883553280 bytes) with the minimum block size of 4K. |
| |
| This causes variable overflow. |
| |
| Link: https://lkml.kernel.org/r/20231113160901.6444-1-phillip@squashfs.org.uk |
| Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk> |
| Reported-by: syzbot+604424eb051c2f696163@syzkaller.appspotmail.com |
| Closes: https://lore.kernel.org/all/000000000000b1fda20609ede0d1@google.com/ |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| fs/squashfs/file.c | 3 ++- |
| fs/squashfs/file_direct.c | 6 +++--- |
| 2 files changed, 5 insertions(+), 4 deletions(-) |
| |
| --- a/fs/squashfs/file.c~squashfs-fix-variable-overflow-triggered-by-sysbot |
| +++ a/fs/squashfs/file.c |
| @@ -544,7 +544,8 @@ static void squashfs_readahead(struct re |
| struct squashfs_page_actor *actor; |
| unsigned int nr_pages = 0; |
| struct page **pages; |
| - int i, file_end = i_size_read(inode) >> msblk->block_log; |
| + int i; |
| + loff_t file_end = i_size_read(inode) >> msblk->block_log; |
| unsigned int max_pages = 1UL << shift; |
| |
| readahead_expand(ractl, start, (len | mask) + 1); |
| --- a/fs/squashfs/file_direct.c~squashfs-fix-variable-overflow-triggered-by-sysbot |
| +++ a/fs/squashfs/file_direct.c |
| @@ -26,10 +26,10 @@ int squashfs_readpage_block(struct page |
| struct inode *inode = target_page->mapping->host; |
| struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; |
| |
| - int file_end = (i_size_read(inode) - 1) >> PAGE_SHIFT; |
| + loff_t file_end = (i_size_read(inode) - 1) >> PAGE_SHIFT; |
| int mask = (1 << (msblk->block_log - PAGE_SHIFT)) - 1; |
| - int start_index = target_page->index & ~mask; |
| - int end_index = start_index | mask; |
| + loff_t start_index = target_page->index & ~mask; |
| + loff_t end_index = start_index | mask; |
| int i, n, pages, bytes, res = -ENOMEM; |
| struct page **page; |
| struct squashfs_page_actor *actor; |
| _ |