[lvc-project] [PATCH 6.1/6.12] squashfs: fix i_mode type assignment in squashfs_read_inode
Makar Semyonov
m.semenov at tssltd.ru
Fri Apr 24 14:47:49 MSK 2026
Using |= S_IFREG does not clear existing S_IFMT bits, which can leave
inode with an invalid type and break S_ISREG() checks, triggering WARN_ON
in exec path.
Fix by masking S_IFMT before setting S_IFREG.
Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
Signed-off-by: Makar Semyonov <m.semenov at tssltd.ru>
---
fs/squashfs/inode.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/squashfs/inode.c b/fs/squashfs/inode.c
index d5918eba27e3..a852b0b15cd8 100644
--- a/fs/squashfs/inode.c
+++ b/fs/squashfs/inode.c
@@ -157,7 +157,7 @@ int squashfs_read_inode(struct inode *inode, long long ino)
set_nlink(inode, 1);
inode->i_size = le32_to_cpu(sqsh_ino->file_size);
inode->i_fop = &generic_ro_fops;
- inode->i_mode |= S_IFREG;
+ inode->i_mode = S_IFREG | (inode->i_mode & ~S_IFMT);
inode->i_blocks = ((inode->i_size - 1) >> 9) + 1;
squashfs_i(inode)->fragment_block = frag_blk;
squashfs_i(inode)->fragment_size = frag_size;
@@ -202,7 +202,7 @@ int squashfs_read_inode(struct inode *inode, long long ino)
inode->i_size = le64_to_cpu(sqsh_ino->file_size);
inode->i_op = &squashfs_inode_ops;
inode->i_fop = &generic_ro_fops;
- inode->i_mode |= S_IFREG;
+ inode->i_mode = S_IFREG | (inode->i_mode & ~S_IFMT);
inode->i_blocks = (inode->i_size -
le64_to_cpu(sqsh_ino->sparse) + 511) >> 9;
--
2.43.0
More information about the lvc-project
mailing list