* [PATCH v2 0/2] fs/squashfs: fix directory table integer overflow
@ 2026-07-28 6:55 Shahriyar Jalayeri
2026-07-28 6:55 ` [PATCH v2 1/2] fs/squashfs: fix integer overflow in directory table allocation Shahriyar Jalayeri
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Shahriyar Jalayeri @ 2026-07-28 6:55 UTC (permalink / raw)
To: u-boot, Thomas Petazzoni, Miquel Raynal, Joao Marcos Costa,
u-boot
Cc: Richard Genoud, Tom Rini, Michael Zimmermann, Eric Kilmer, Argus,
Shahriyar Jalayeri
This fixes an integer overflow in the SquashFS directory-table reader
that leads to a heap out-of-bounds write, and adds a regression test.
sqfs_read_directory_table() sizes the directory table with an int
multiply (metablks_count * SQFS_METADATA_BLOCK_SIZE) that wraps for a
crafted image, under-allocating the buffer that the fill loop then
overruns. It is reached by listing or reading the image (sqfsls /
sqfsload). Patch 1 guards the allocation with __builtin_mul_overflow();
patch 2 adds a test that a crafted image is rejected.
Based on v2026.07 (fdfe2ec48d5c). A reproducer is available on request.
Signed-off-by: Shahriyar Jalayeri <shahriyar@byteray.co.uk>
---
Changes in v2:
- Use my real name in the From and Signed-off-by
---
Shahriyar Jalayeri (2):
fs/squashfs: fix integer overflow in directory table allocation
test: squashfs: add directory table overflow regression test
fs/squashfs/sqfs.c | 23 +++++--
.../test_fs/test_squashfs/test_sqfs_overflow.py | 75 ++++++++++++++++++++++
2 files changed, 94 insertions(+), 4 deletions(-)
---
base-commit: fdfe2ec48d5c1c2ed03073d73edd3fdd3fe1ffa1
change-id: 20260723-sqfs-oob-fix-e202a643c3d8
Best regards,
--
Shahriyar Jalayeri <shahriyar@byteray.co.uk>
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 1/2] fs/squashfs: fix integer overflow in directory table allocation
2026-07-28 6:55 [PATCH v2 0/2] fs/squashfs: fix directory table integer overflow Shahriyar Jalayeri
@ 2026-07-28 6:55 ` Shahriyar Jalayeri
2026-07-28 6:55 ` [PATCH v2 2/2] test: squashfs: add directory table overflow regression test Shahriyar Jalayeri
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Shahriyar Jalayeri @ 2026-07-28 6:55 UTC (permalink / raw)
To: u-boot, Thomas Petazzoni, Miquel Raynal, Joao Marcos Costa,
u-boot
Cc: Richard Genoud, Tom Rini, Michael Zimmermann, Eric Kilmer, Argus,
Shahriyar Jalayeri
sqfs_read_directory_table() allocates the directory table with
malloc(metablks_count * SQFS_METADATA_BLOCK_SIZE). metablks_count is an
int and SQFS_METADATA_BLOCK_SIZE is 8192, so the multiply is evaluated in
int and wraps for metablks_count >= 2^19. metablks_count comes from the
attacker-controlled superblock (sqfs_count_metablks() grows it by one per
2-byte metadata header), so a crafted image under-allocates the buffer
while the fill loop still writes metablks_count metadata blocks into it,
a heap out-of-bounds write. It is reached by listing or reading the image
(sqfsls / sqfsload). The position list allocation on the next line has the
same unchecked-multiply shape.
Size both allocations with __builtin_mul_overflow() and reject the image
on overflow, as the disk-read buffers earlier in the same function already
do. Set the error return when either allocation fails so the caller does
not proceed with a NULL directory table.
Fixes: c51006130370 ("fs/squashfs: new filesystem")
Signed-off-by: Shahriyar Jalayeri <shahriyar@byteray.co.uk>
---
fs/squashfs/sqfs.c | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c
index 0768fc4a7b2..3aadcdd36ec 100644
--- a/fs/squashfs/sqfs.c
+++ b/fs/squashfs/sqfs.c
@@ -852,13 +852,28 @@ static int sqfs_read_directory_table(unsigned char **dir_table, u32 **pos_list)
if (metablks_count < 1)
goto out;
- *dir_table = malloc(metablks_count * SQFS_METADATA_BLOCK_SIZE);
- if (!*dir_table)
+ if (__builtin_mul_overflow(metablks_count, SQFS_METADATA_BLOCK_SIZE,
+ &buf_size)) {
+ metablks_count = -1;
+ goto out;
+ }
+
+ *dir_table = malloc(buf_size);
+ if (!*dir_table) {
+ metablks_count = -1;
+ goto out;
+ }
+
+ if (__builtin_mul_overflow(metablks_count, sizeof(u32), &buf_size)) {
+ metablks_count = -1;
goto out;
+ }
- *pos_list = malloc(metablks_count * sizeof(u32));
- if (!*pos_list)
+ *pos_list = malloc(buf_size);
+ if (!*pos_list) {
+ metablks_count = -1;
goto out;
+ }
ret = sqfs_get_metablk_pos(*pos_list, dtb, table_offset,
metablks_count);
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 2/2] test: squashfs: add directory table overflow regression test
2026-07-28 6:55 [PATCH v2 0/2] fs/squashfs: fix directory table integer overflow Shahriyar Jalayeri
2026-07-28 6:55 ` [PATCH v2 1/2] fs/squashfs: fix integer overflow in directory table allocation Shahriyar Jalayeri
@ 2026-07-28 6:55 ` Shahriyar Jalayeri
2026-08-26 22:32 ` [PATCH v2 0/2] fs/squashfs: fix directory table integer overflow Tom Rini
2026-08-27 23:53 ` Tom Rini
3 siblings, 0 replies; 6+ messages in thread
From: Shahriyar Jalayeri @ 2026-07-28 6:55 UTC (permalink / raw)
To: u-boot, Thomas Petazzoni, Miquel Raynal, Joao Marcos Costa,
u-boot
Cc: Richard Genoud, Tom Rini, Michael Zimmermann, Eric Kilmer, Argus,
Shahriyar Jalayeri
Add a Python test that lists a crafted SquashFS image whose directory
table declares an oversized metadata-block count. Such an image must be
rejected without corrupting the heap, which the test checks by confirming
U-Boot is still responsive afterwards.
Signed-off-by: Shahriyar Jalayeri <shahriyar@byteray.co.uk>
---
.../test_fs/test_squashfs/test_sqfs_overflow.py | 75 ++++++++++++++++++++++
1 file changed, 75 insertions(+)
diff --git a/test/py/tests/test_fs/test_squashfs/test_sqfs_overflow.py b/test/py/tests/test_fs/test_squashfs/test_sqfs_overflow.py
new file mode 100644
index 00000000000..df7f875a58f
--- /dev/null
+++ b/test/py/tests/test_fs/test_squashfs/test_sqfs_overflow.py
@@ -0,0 +1,75 @@
+# SPDX-License-Identifier: GPL-2.0
+# Regression test for the SquashFS directory-table integer overflow.
+
+import os
+import struct
+import pytest
+
+# metadata block size (SQFS_METADATA_BLOCK_SIZE) and metadata header size
+SQFS_METADATA_BLOCK_SIZE = 8192
+# metablks_count that makes metablks_count * SQFS_METADATA_BLOCK_SIZE wrap a
+# 32-bit int back down to a tiny value: (2^19 + 1) * 8192 == 2^32 + 8192.
+NR_METABLKS = (1 << 19) + 1
+
+def make_overflow_image(path):
+ """Build a SquashFS image whose directory table inflates metablks_count so
+ that metablks_count * SQFS_METADATA_BLOCK_SIZE wraps a 32-bit int, then
+ writes one block of data one metadata block past the resulting buffer."""
+ def metahdr(size):
+ # uncompressed metadata block header (bit 15 set)
+ return struct.pack('<H', 0x8000 | (size & 0x7fff))
+
+ # inode table: one small valid uncompressed metadata block
+ inode_region = metahdr(32) + b'\x00' * 32
+ inode_start = 96
+ dir_start = inode_start + len(inode_region)
+
+ # directory table: NR_METABLKS metadata blocks, only block 1 carries data
+ dir_region = bytearray()
+ dir_region += metahdr(0) # block 0: empty
+ dir_region += metahdr(200) + b'A' * 200 # block 1: data
+ dir_region += metahdr(0) * (NR_METABLKS - 2) # blocks 2..N-1: empty
+ frag_start = dir_start + len(dir_region)
+
+ sb = bytearray(96)
+ struct.pack_into('<I', sb, 0, 0x73717368) # s_magic
+ struct.pack_into('<I', sb, 4, 1) # inodes
+ struct.pack_into('<I', sb, 12, 131072) # block_size
+ struct.pack_into('<H', sb, 20, 1) # compression = gzip/zlib
+ struct.pack_into('<H', sb, 22, 17) # block_log
+ struct.pack_into('<H', sb, 26, 1) # no_ids
+ struct.pack_into('<H', sb, 28, 4) # s_major
+ struct.pack_into('<Q', sb, 48, frag_start) # id_table_start
+ struct.pack_into('<Q', sb, 56, 0xffffffffffffffff) # xattr_id_table_start
+ struct.pack_into('<Q', sb, 64, inode_start) # inode_table_start
+ struct.pack_into('<Q', sb, 72, dir_start) # directory_table_start
+ struct.pack_into('<Q', sb, 80, frag_start) # fragment_table_start
+ struct.pack_into('<Q', sb, 88, 0xffffffffffffffff) # export_table_start
+
+ img = bytearray(sb) + inode_region + dir_region
+ # pad so the directory-table block read stays within the file
+ need = ((len(img) + 511) // 512 + 1) * 512
+ img += b'\x00' * (need - len(img))
+ struct.pack_into('<Q', img, 40, len(img)) # bytes_used
+
+ with open(path, 'wb') as f:
+ f.write(img)
+
+@pytest.mark.boardspec('sandbox')
+@pytest.mark.buildconfigspec('cmd_squashfs')
+@pytest.mark.buildconfigspec('fs_squashfs')
+@pytest.mark.singlethread
+def test_sqfs_ls_dir_table_overflow(ubman):
+ """Listing a crafted image whose directory table declares an oversized
+ metadata-block count must be rejected without corrupting the heap.
+ """
+ ubman.restart_uboot()
+ image_path = os.path.join(ubman.config.build_dir, 'sqfs_dir_table_overflow')
+ make_overflow_image(image_path)
+ try:
+ ubman.run_command('host bind 0 {}'.format(image_path))
+ ubman.run_command('sqfsls host 0')
+ # The crafted image must not take the board down.
+ assert 'alive' in ubman.run_command('echo alive')
+ finally:
+ os.remove(image_path)
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v2 0/2] fs/squashfs: fix directory table integer overflow
2026-07-28 6:55 [PATCH v2 0/2] fs/squashfs: fix directory table integer overflow Shahriyar Jalayeri
2026-07-28 6:55 ` [PATCH v2 1/2] fs/squashfs: fix integer overflow in directory table allocation Shahriyar Jalayeri
2026-07-28 6:55 ` [PATCH v2 2/2] test: squashfs: add directory table overflow regression test Shahriyar Jalayeri
@ 2026-08-26 22:32 ` Tom Rini
2026-08-27 7:25 ` Richard GENOUD
2026-08-27 23:53 ` Tom Rini
3 siblings, 1 reply; 6+ messages in thread
From: Tom Rini @ 2026-08-26 22:32 UTC (permalink / raw)
To: Shahriyar Jalayeri
Cc: u-boot, Thomas Petazzoni, Miquel Raynal, Joao Marcos Costa,
u-boot, Richard Genoud, Michael Zimmermann, Eric Kilmer, Argus
[-- Attachment #1: Type: text/plain, Size: 923 bytes --]
On Tue, Jul 28, 2026 at 08:55:38AM +0200, Shahriyar Jalayeri wrote:
> This fixes an integer overflow in the SquashFS directory-table reader
> that leads to a heap out-of-bounds write, and adds a regression test.
>
> sqfs_read_directory_table() sizes the directory table with an int
> multiply (metablks_count * SQFS_METADATA_BLOCK_SIZE) that wraps for a
> crafted image, under-allocating the buffer that the fill loop then
> overruns. It is reached by listing or reading the image (sqfsls /
> sqfsload). Patch 1 guards the allocation with __builtin_mul_overflow();
> patch 2 adds a test that a crafted image is rejected.
>
> Based on v2026.07 (fdfe2ec48d5c). A reproducer is available on request.
>
> Signed-off-by: Shahriyar Jalayeri <shahriyar@byteray.co.uk>
> ---
> Changes in v2:
> - Use my real name in the From and Signed-off-by
Any feedback from the squashfs custodians? Thanks!
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 0/2] fs/squashfs: fix directory table integer overflow
2026-08-26 22:32 ` [PATCH v2 0/2] fs/squashfs: fix directory table integer overflow Tom Rini
@ 2026-08-27 7:25 ` Richard GENOUD
0 siblings, 0 replies; 6+ messages in thread
From: Richard GENOUD @ 2026-08-27 7:25 UTC (permalink / raw)
To: Tom Rini, Shahriyar Jalayeri
Cc: u-boot, Thomas Petazzoni, Miquel Raynal, Joao Marcos Costa,
u-boot, Michael Zimmermann, Eric Kilmer, Argus
Le 27/08/2026 à 00:32, Tom Rini a écrit :
> On Tue, Jul 28, 2026 at 08:55:38AM +0200, Shahriyar Jalayeri wrote:
>
>> This fixes an integer overflow in the SquashFS directory-table reader
>> that leads to a heap out-of-bounds write, and adds a regression test.
>>
>> sqfs_read_directory_table() sizes the directory table with an int
>> multiply (metablks_count * SQFS_METADATA_BLOCK_SIZE) that wraps for a
>> crafted image, under-allocating the buffer that the fill loop then
>> overruns. It is reached by listing or reading the image (sqfsls /
>> sqfsload). Patch 1 guards the allocation with __builtin_mul_overflow();
>> patch 2 adds a test that a crafted image is rejected.
>>
>> Based on v2026.07 (fdfe2ec48d5c). A reproducer is available on request.
>>
>> Signed-off-by: Shahriyar Jalayeri <shahriyar@byteray.co.uk>
>> ---
>> Changes in v2:
>> - Use my real name in the From and Signed-off-by
>
> Any feedback from the squashfs custodians? Thanks!
>
Nice patch, looks great!
Reviewed-by: Richard Genoud <richard.genoud@bootlin.com>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 0/2] fs/squashfs: fix directory table integer overflow
2026-07-28 6:55 [PATCH v2 0/2] fs/squashfs: fix directory table integer overflow Shahriyar Jalayeri
` (2 preceding siblings ...)
2026-08-26 22:32 ` [PATCH v2 0/2] fs/squashfs: fix directory table integer overflow Tom Rini
@ 2026-08-27 23:53 ` Tom Rini
3 siblings, 0 replies; 6+ messages in thread
From: Tom Rini @ 2026-08-27 23:53 UTC (permalink / raw)
To: u-boot, Thomas Petazzoni, Miquel Raynal, Joao Marcos Costa,
u-boot, Shahriyar Jalayeri
Cc: Richard Genoud, Michael Zimmermann, Eric Kilmer, Argus
On Tue, 28 Jul 2026 08:55:38 +0200, Shahriyar Jalayeri wrote:
> This fixes an integer overflow in the SquashFS directory-table reader
> that leads to a heap out-of-bounds write, and adds a regression test.
>
> sqfs_read_directory_table() sizes the directory table with an int
> multiply (metablks_count * SQFS_METADATA_BLOCK_SIZE) that wraps for a
> crafted image, under-allocating the buffer that the fill loop then
> overruns. It is reached by listing or reading the image (sqfsls /
> sqfsload). Patch 1 guards the allocation with __builtin_mul_overflow();
> patch 2 adds a test that a crafted image is rejected.
>
> [...]
Applied to u-boot/main, thanks!
[1/2] fs/squashfs: fix integer overflow in directory table allocation
commit: 561ae28cb56a082cfa90c1c421c4955bc215470b
[2/2] test: squashfs: add directory table overflow regression test
commit: 4750bcfe857c5a0feda86b54f260a11a4e3222cd
--
Tom
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-08-27 23:54 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-28 6:55 [PATCH v2 0/2] fs/squashfs: fix directory table integer overflow Shahriyar Jalayeri
2026-07-28 6:55 ` [PATCH v2 1/2] fs/squashfs: fix integer overflow in directory table allocation Shahriyar Jalayeri
2026-07-28 6:55 ` [PATCH v2 2/2] test: squashfs: add directory table overflow regression test Shahriyar Jalayeri
2026-08-26 22:32 ` [PATCH v2 0/2] fs/squashfs: fix directory table integer overflow Tom Rini
2026-08-27 7:25 ` Richard GENOUD
2026-08-27 23:53 ` Tom Rini
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.