From: Pavel Skripkin <paskripkin@gmail.com>
To: phillip@squashfs.org.uk
Cc: linux-kernel@vger.kernel.org,
Pavel Skripkin <paskripkin@gmail.com>,
stable@vger.kernel.org,
syzbot+e8f781243ce16ac2f962@syzkaller.appspotmail.com
Subject: [PATCH] squashfs: fix divide error
Date: Tue, 4 May 2021 11:05:52 +0300 [thread overview]
Message-ID: <20210504080552.21473-1-paskripkin@gmail.com> (raw)
The problem was in calculate_skip() function.
int skip = calculate_skip(i_size_read(inode) >> msblk->block_log);
i_size_read(inode) and msblk->block_log are unsigned integers,
but calculate_skip had a signed int as argument. This cast led
to wrong skip value and then to divide by zero bug.
Fixes: 1701aecb6849 ("Squashfs: regular file operations")
Cc: stable@vger.kernel.org
Reported-by: syzbot+e8f781243ce16ac2f962@syzkaller.appspotmail.com
Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
---
fs/squashfs/file.c | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/fs/squashfs/file.c b/fs/squashfs/file.c
index 7b1128398976..2ebcbd4f84cc 100644
--- a/fs/squashfs/file.c
+++ b/fs/squashfs/file.c
@@ -44,8 +44,8 @@
* Locate cache slot in range [offset, index] for specified inode. If
* there's more than one return the slot closest to index.
*/
-static struct meta_index *locate_meta_index(struct inode *inode, int offset,
- int index)
+static struct meta_index *locate_meta_index(struct inode *inode, unsigned int offset,
+ unsigned int index)
{
struct meta_index *meta = NULL;
struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
@@ -83,8 +83,8 @@ static struct meta_index *locate_meta_index(struct inode *inode, int offset,
/*
* Find and initialise an empty cache slot for index offset.
*/
-static struct meta_index *empty_meta_index(struct inode *inode, int offset,
- int skip)
+static struct meta_index *empty_meta_index(struct inode *inode, unsigned int offset,
+ unsigned int skip)
{
struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
struct meta_index *meta = NULL;
@@ -211,11 +211,11 @@ static long long read_indexes(struct super_block *sb, int n,
* If the skip factor is limited in this way then the file will use multiple
* slots.
*/
-static inline int calculate_skip(int blocks)
+static inline unsigned int calculate_skip(unsigned int blocks)
{
- int skip = blocks / ((SQUASHFS_META_ENTRIES + 1)
+ unsigned int skip = blocks / ((SQUASHFS_META_ENTRIES + 1)
* SQUASHFS_META_INDEXES);
- return min(SQUASHFS_CACHED_BLKS - 1, skip + 1);
+ return min((unsigned int) SQUASHFS_CACHED_BLKS - 1, skip + 1);
}
@@ -224,12 +224,12 @@ static inline int calculate_skip(int blocks)
* on-disk locations of the datablock and block list metadata block
* <index_block, index_offset> for index (scaled to nearest cache index).
*/
-static int fill_meta_index(struct inode *inode, int index,
+static int fill_meta_index(struct inode *inode, unsigned int index,
u64 *index_block, int *index_offset, u64 *data_block)
{
struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
- int skip = calculate_skip(i_size_read(inode) >> msblk->block_log);
- int offset = 0;
+ unsigned int skip = calculate_skip(i_size_read(inode) >> msblk->block_log);
+ unsigned int offset = 0;
struct meta_index *meta;
struct meta_entry *meta_entry;
u64 cur_index_block = squashfs_i(inode)->block_list_start;
@@ -323,7 +323,7 @@ static int fill_meta_index(struct inode *inode, int index,
* Get the on-disk location and compressed size of the datablock
* specified by index. Fill_meta_index() does most of the work.
*/
-static int read_blocklist(struct inode *inode, int index, u64 *block)
+static int read_blocklist(struct inode *inode, unsigned int index, u64 *block)
{
u64 start;
long long blks;
@@ -448,7 +448,7 @@ static int squashfs_readpage(struct file *file, struct page *page)
{
struct inode *inode = page->mapping->host;
struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
- int index = page->index >> (msblk->block_log - PAGE_SHIFT);
+ unsigned int index = page->index >> (msblk->block_log - PAGE_SHIFT);
int file_end = i_size_read(inode) >> msblk->block_log;
int expected = index == file_end ?
(i_size_read(inode) & (msblk->block_size - 1)) :
--
2.31.1
reply other threads:[~2021-05-04 8:06 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210504080552.21473-1-paskripkin@gmail.com \
--to=paskripkin@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=phillip@squashfs.org.uk \
--cc=stable@vger.kernel.org \
--cc=syzbot+e8f781243ce16ac2f962@syzkaller.appspotmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox