Skip to content

Commit 234f6e1

Browse files
ploughergregkh
authored andcommitted
Squashfs: add additional inode sanity checking
[ Upstream commit 9ee94bf ] Patch series "Squashfs: performance improvement and a sanity check". This patchset adds an additional sanity check when reading regular file inodes, and adds support for SEEK_DATA/SEEK_HOLE lseek() whence values. This patch (of 2): Add an additional sanity check when reading regular file inodes. A regular file if the file size is an exact multiple of the filesystem block size cannot have a fragment. This is because by definition a fragment block stores tailends which are not a whole block in size. Link: https://lkml.kernel.org/r/[email protected] Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Phillip Lougher <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Stable-dep-of: 9f1c14c ("Squashfs: reject negative file sizes in squashfs_read_inode()") Signed-off-by: Sasha Levin <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 7db47e7 commit 234f6e1

File tree

1 file changed

+18
-2
lines changed

1 file changed

+18
-2
lines changed

fs/squashfs/inode.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,17 @@ int squashfs_read_inode(struct inode *inode, long long ino)
140140
if (err < 0)
141141
goto failed_read;
142142

143+
inode->i_size = le32_to_cpu(sqsh_ino->file_size);
143144
frag = le32_to_cpu(sqsh_ino->fragment);
144145
if (frag != SQUASHFS_INVALID_FRAG) {
146+
/*
147+
* the file cannot have a fragment (tailend) and have a
148+
* file size a multiple of the block size
149+
*/
150+
if ((inode->i_size & (msblk->block_size - 1)) == 0) {
151+
err = -EINVAL;
152+
goto failed_read;
153+
}
145154
frag_offset = le32_to_cpu(sqsh_ino->offset);
146155
frag_size = squashfs_frag_lookup(sb, frag, &frag_blk);
147156
if (frag_size < 0) {
@@ -155,7 +164,6 @@ int squashfs_read_inode(struct inode *inode, long long ino)
155164
}
156165

157166
set_nlink(inode, 1);
158-
inode->i_size = le32_to_cpu(sqsh_ino->file_size);
159167
inode->i_fop = &generic_ro_fops;
160168
inode->i_mode |= S_IFREG;
161169
inode->i_blocks = ((inode->i_size - 1) >> 9) + 1;
@@ -184,8 +192,17 @@ int squashfs_read_inode(struct inode *inode, long long ino)
184192
if (err < 0)
185193
goto failed_read;
186194

195+
inode->i_size = le64_to_cpu(sqsh_ino->file_size);
187196
frag = le32_to_cpu(sqsh_ino->fragment);
188197
if (frag != SQUASHFS_INVALID_FRAG) {
198+
/*
199+
* the file cannot have a fragment (tailend) and have a
200+
* file size a multiple of the block size
201+
*/
202+
if ((inode->i_size & (msblk->block_size - 1)) == 0) {
203+
err = -EINVAL;
204+
goto failed_read;
205+
}
189206
frag_offset = le32_to_cpu(sqsh_ino->offset);
190207
frag_size = squashfs_frag_lookup(sb, frag, &frag_blk);
191208
if (frag_size < 0) {
@@ -200,7 +217,6 @@ int squashfs_read_inode(struct inode *inode, long long ino)
200217

201218
xattr_id = le32_to_cpu(sqsh_ino->xattr);
202219
set_nlink(inode, le32_to_cpu(sqsh_ino->nlink));
203-
inode->i_size = le64_to_cpu(sqsh_ino->file_size);
204220
inode->i_op = &squashfs_inode_ops;
205221
inode->i_fop = &generic_ro_fops;
206222
inode->i_mode |= S_IFREG;

0 commit comments

Comments
 (0)