summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2026-08-27 15:05:06 -0600
committerTom Rini <[email protected]>2026-08-27 15:05:06 -0600
commit658fc6aee95784139f070f9945cb3bc5da8d7d22 (patch)
tree1e8bd0eb2c2666181e89b59fb88e079b90855f31 /fs
parentced85f31db7abb858db2f88894e0166a177e3192 (diff)
parent4750bcfe857c5a0feda86b54f260a11a4e3222cd (diff)
Merge patch series "fs/squashfs: fix directory table integer overflow"HEADmain
Shahriyar Jalayeri <[email protected]> says: 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. [trini: As part of the merge, this touches on what commit 9a9d46cb5e1a ("fs/squashfs: fix heap exhaustion during symlink resolution") also handles, but they appear to be separate issues] Link: https://lore.kernel.org/r/[email protected]
Diffstat (limited to 'fs')
-rw-r--r--fs/squashfs/sqfs.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c
index cd88923521e..e2741380f93 100644
--- a/fs/squashfs/sqfs.c
+++ b/fs/squashfs/sqfs.c
@@ -910,13 +910,24 @@ 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 (__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;
}
- *pos_list = malloc(metablks_count * sizeof(u32));
+ if (__builtin_mul_overflow(metablks_count, sizeof(u32), &buf_size)) {
+ metablks_count = -1;
+ goto out;
+ }
+
+ *pos_list = malloc(buf_size);
if (!*pos_list) {
metablks_count = -1;
goto out;