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