mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Phillip Lougher <phillip@squashfs.org.uk>
To: akpm@linux-foundation.org, linux-kernel@vger.kernel.org
Cc: Phillip Lougher <phillip@squashfs.org.uk>
Subject: [PATCH 07/18] Squashfs: fix fragment bytes overflow on 32-bit architectures
Date: Sat,  7 Nov 2026 05:28:32 +0000	[thread overview]
Message-ID: <20261107052843.725239-8-phillip@squashfs.org.uk> (raw)
In-Reply-To: <20261107052843.725239-1-phillip@squashfs.org.uk>

In helper function squashfs_fragment_bytes() the u32 fragments
variable is multiplied by sizeof(struct squashfs_fragment_enty).

On a 32-bit architecture the type of sizeof() is a 32-bit unsigned
integer, which means the computation will overflow for fragments
values above 268435455.

The knock-on effect is the size of the in memory fragment index
table will be incorrectly computed, and a much smaller than expected
index table will be allocated and read into memory.

Later when a fragment index beyond this is looked up in this table,
this will produce an out of bounds access.

The fix is to explicitly widen the fragments variable to a long long
in the squashfs_fragment_bytes() helper function.

Reproducer
=========

The following script when run on a 32-bit x86 kernel (which lacks
KASAN support) will produce an I/O error.  On a 32-bit ARM kernel
with KASAN enabled, the out of bounds access will also produce a
KASAN report.

[  193.817260] ==================================================================
[  193.818057] BUG: KASAN: slab-out-of-bounds in squashfs_frag_lookup+0x23c/0x264
[  193.820408] Read of size 8 at addr cc126708 by task stat/357
[  193.820720]
[  193.821675] CPU: 3 UID: 0 PID: 357 Comm: stat Not tainted 7.2.0-13187-g66498c75b4f8 #113 VOLUNTARY

=================================================================
#!/bin/bash

ARGS="-no-duplicates -no-sparse -no-hardlinks -quiet -no-progress"

finish() {
	popd 2>&1 > /dev/null
	rm -rf $DIR
	exit 1
}

# Create a Squashfs filesystem with 1026 files and 513 fragments.
# This will create a two entry Squashfs fragment index table.
#
DIR=$(mktemp -d)

pushd $DIR 2>&1 > /dev/null

# Create a Squashfs pseudo file which is fed to Mksquashfs
echo Create a Squashfs pseudo file which is fed to Mksquashfs

dd if=/dev/urandom of=urandom bs=1024 count=50 status=none
for i in $(seq 1 1026); do
	echo "$i l urandom" >> pseudo
done

# Create the Squashfs filesystem
echo Create the Squashfs filesystem

if ! mksquashfs - img.sqsh -pf pseudo -p "/ d 0777 0 0" $ARGS; then
	echo Failed to create Squashfs filesystem
	finish

fi

# The fragments field (fragment count) in the superblock is at offset
# 16 bytes.
#
# Over-write the fragments count with 268,435,457 little-endian.  On a
# 32-bit architecture, this when multiplied by 16 will overflow, giving
# the value 16.
#
# Ultimately this will cause the kernel code to create and read a single
# entry index table (where in fact the table has two entries).
#
# Then stating file 999 which has a fragment id in the second index,
# will cause an out of bounds access.

# Write 268,435,457 in little-endian format to file
/usr/bin/echo -en "\x01\x00\x00\x10" > file

# Over-write the fragments count in the superblock
echo Over-write the fragments count in the superblock

dd bs=1 seek=16 if=file of=img.sqsh count=4 conv=notrunc status=none

# Mount the filesystem to /mnt
echo Mount the filesystem to /mnt

if ! mount -t squashfs img.sqsh /mnt; then
	echo Mount of Squashfs filesystem failed
	finish
fi

# Stat file 999
echo Stat file 999

stat /mnt/999

popd 2>&1 > /dev/null

rm -rf $DIR
=================================================================

Fixes: ffae2cd73a9e ("Squashfs: header files")
Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
---
 fs/squashfs/squashfs_helpers.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/squashfs/squashfs_helpers.h b/fs/squashfs/squashfs_helpers.h
index 4088e598400f..524d4a77686d 100644
--- a/fs/squashfs/squashfs_helpers.h
+++ b/fs/squashfs/squashfs_helpers.h
@@ -55,7 +55,7 @@ static inline s64 squashfs_mkinode(u32 start, u16 offset)
 /* fragment and fragment table defines */
 static inline s64 squashfs_fragment_bytes(u32 fragments)
 {
-	return fragments * sizeof(struct squashfs_fragment_entry);
+	return (s64) fragments * sizeof(struct squashfs_fragment_entry);
 }
 
 static inline s32 squashfs_fragment_index(u32 fragments)
-- 
2.47.3


  parent reply	other threads:[~2026-11-07  5:29 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-07  5:28 [PATCH 00/18] Squashfs: fix a lot of AI issues and AI style issues Phillip Lougher
2026-11-07  5:28 ` [PATCH 01/18] Squashfs: convert SQUASHFS_COMPRESSED_* to inline functions Phillip Lougher
2026-11-07  5:28 ` [PATCH 02/18] Squashfs: convert SQUASHFS_INODE_* and SQUASHFS_MKINODE " Phillip Lougher
2026-11-07  5:28 ` [PATCH 03/18] Squashfs: convert SQUASHFS_FRAGMENT_* " Phillip Lougher
2026-11-07  5:28 ` [PATCH 04/18] Squashfs: convert SQUASHFS_LOOKUP_* " Phillip Lougher
2026-11-07  5:28 ` [PATCH 05/18] Squashfs: convert SQUASHFS_ID_* " Phillip Lougher
2026-11-07  5:28 ` [PATCH 06/18] Squashfs: convert SQUASHFS_XATTR_* " Phillip Lougher
2026-11-07  5:28 ` Phillip Lougher [this message]
2026-11-07  5:28 ` [PATCH 08/18] Squashfs: fix fragment index table length too large exploit Phillip Lougher
2026-11-07  5:28 ` [PATCH 09/18] Squashfs: sanity check inode metadata block location Phillip Lougher
2026-11-07  5:28 ` [PATCH 10/18] Squashfs: sanity check directory " Phillip Lougher
2026-11-07  5:28 ` [PATCH 11/18] Squashfs: widen xattr count variables and add sanity check Phillip Lougher
2026-11-07  5:28 ` [PATCH 12/18] Squashfs: very large files can exceed an int block count Phillip Lougher
2026-11-07  5:28 ` [PATCH 13/18] Squashfs: add more sanity checking to squashfs_block_size() Phillip Lougher
2026-11-07  5:28 ` [PATCH 14/18] Squashfs: sanity check fragment block location and range Phillip Lougher
2026-11-07  5:28 ` [PATCH 15/18] Squashfs: sanity check block list sizes " Phillip Lougher
2026-11-07  5:28 ` [PATCH 16/18] Squashfs: don't store large export table indexes in memory Phillip Lougher
2026-11-07  5:28 ` [PATCH 17/18] Squashfs: don't store large fragment " Phillip Lougher
2026-11-07  5:28 ` [PATCH 18/18] Squashfs: don't store large xattr id " Phillip Lougher

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261107052843.725239-8-phillip@squashfs.org.uk \
    --to=phillip@squashfs.org.uk \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®