Skip to content

Commit 9ee94bf

Browse files
plougherakpm00
authored andcommitted
Squashfs: add additional inode sanity checking
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]>
1 parent 1260cbc commit 9ee94bf

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
@@ -144,8 +144,17 @@ int squashfs_read_inode(struct inode *inode, long long ino)
144144
if (err < 0)
145145
goto failed_read;
146146

147+
inode->i_size = le32_to_cpu(sqsh_ino->file_size);
147148
frag = le32_to_cpu(sqsh_ino->fragment);
148149
if (frag != SQUASHFS_INVALID_FRAG) {
150+
/*
151+
* the file cannot have a fragment (tailend) and have a
152+
* file size a multiple of the block size
153+
*/
154+
if ((inode->i_size & (msblk->block_size - 1)) == 0) {
155+
err = -EINVAL;
156+
goto failed_read;
157+
}
149158
frag_offset = le32_to_cpu(sqsh_ino->offset);
150159
frag_size = squashfs_frag_lookup(sb, frag, &frag_blk);
151160
if (frag_size < 0) {
@@ -159,7 +168,6 @@ int squashfs_read_inode(struct inode *inode, long long ino)
159168
}
160169

161170
set_nlink(inode, 1);
162-
inode->i_size = le32_to_cpu(sqsh_ino->file_size);
163171
inode->i_fop = &generic_ro_fops;
164172
inode->i_mode |= S_IFREG;
165173
inode->i_blocks = ((inode->i_size - 1) >> 9) + 1;
@@ -188,8 +196,17 @@ int squashfs_read_inode(struct inode *inode, long long ino)
188196
if (err < 0)
189197
goto failed_read;
190198

199+
inode->i_size = le64_to_cpu(sqsh_ino->file_size);
191200
frag = le32_to_cpu(sqsh_ino->fragment);
192201
if (frag != SQUASHFS_INVALID_FRAG) {
202+
/*
203+
* the file cannot have a fragment (tailend) and have a
204+
* file size a multiple of the block size
205+
*/
206+
if ((inode->i_size & (msblk->block_size - 1)) == 0) {
207+
err = -EINVAL;
208+
goto failed_read;
209+
}
193210
frag_offset = le32_to_cpu(sqsh_ino->offset);
194211
frag_size = squashfs_frag_lookup(sb, frag, &frag_blk);
195212
if (frag_size < 0) {
@@ -204,7 +221,6 @@ int squashfs_read_inode(struct inode *inode, long long ino)
204221

205222
xattr_id = le32_to_cpu(sqsh_ino->xattr);
206223
set_nlink(inode, le32_to_cpu(sqsh_ino->nlink));
207-
inode->i_size = le64_to_cpu(sqsh_ino->file_size);
208224
inode->i_op = &squashfs_inode_ops;
209225
inode->i_fop = &generic_ro_fops;
210226
inode->i_mode |= S_IFREG;

0 commit comments

Comments
 (0)