[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