[PATCH 1/5] CVE-2025-26722: fs: squashfs: Ensure positive inode length

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



In squashfs_get_link() we have:

	int length = min_t(int, i_size_read(inode), PAGE_SIZE);

The inode size is a 64bit number directly read from the device which
is interpreted as a 32bit signed number above. An inode size with the
lower 32bits set to 0xffffffff results in length being -1. Later we
do a:

	symlink = malloc(length + 1);

With length being -1 this results in allocating a zero size buffer which
is then overwritten by following code.

Fix this by first making sure that the inode length is positive.
Afterwards limit the length to the desired range, explicitly using
loff_t as the type to compare to make sure we do not truncate the
original data type during comparison.

Reported-by: Jonathan Bar Or <jonathanbaror@xxxxxxxxx>
Signed-off-by: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx>
---
 fs/squashfs/symlink.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/fs/squashfs/symlink.c b/fs/squashfs/symlink.c
index 40b9bdcc8b..cb14eb20a5 100644
--- a/fs/squashfs/symlink.c
+++ b/fs/squashfs/symlink.c
@@ -43,16 +43,20 @@
 static const char *squashfs_get_link(struct dentry *dentry, struct inode *inode)
 {
 	struct super_block *sb = inode->i_sb;
-	int index = 0;
 	u64 block = squashfs_i(inode)->start;
 	int offset = squashfs_i(inode)->offset;
-	int length = min_t(int, i_size_read(inode) - index, PAGE_SIZE);
+	size_t length;
 	int bytes;
 	unsigned char *symlink;
 
 	TRACE("Entered squashfs_symlink_readpage, start block "
 			"%llx, offset %x\n", block, offset);
 
+	if (i_size_read(inode) < 0)
+		return NULL;
+
+	length = min_t(loff_t, i_size_read(inode), PAGE_SIZE);
+
 	symlink = malloc(length + 1);
 	if (!symlink)
 		return NULL;
-- 
2.39.5





[Index of Archives]     [Linux Embedded]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux