<feed xmlns='http://www.w3.org/2005/Atom'>
<title>u-boot.git/fs, branch main</title>
<subtitle>Unnamed repository; edit this file 'description' to name the repository.</subtitle>
<id>http://cgit.235523.xyz/u-boot.git/atom/fs?h=main</id>
<link rel='self' href='http://cgit.235523.xyz/u-boot.git/atom/fs?h=main'/>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/u-boot.git/'/>
<updated>2026-08-28T15:00:06Z</updated>
<entry>
<title>Merge patch series "fs/squashfs: fix two out-of-bounds reads on crafted images"</title>
<updated>2026-08-28T15:00:06Z</updated>
<author>
<name>Tom Rini</name>
<email>trini@konsulko.com</email>
</author>
<published>2026-08-28T15:00:06Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/u-boot.git/commit/?id=d40f495e14d6ed1ec401cbe4bdc793cd9ed87d20'/>
<id>urn:sha1:d40f495e14d6ed1ec401cbe4bdc793cd9ed87d20</id>
<content type='text'>
Piyush Paliwal &lt;piyushthepal@gmail.com&gt; says:

Two independent out-of-bounds reads in the SquashFS driver, both reachable
by pointing U-Boot at an attacker-supplied image (e.g. ls/load on a crafted
USB/SD/netboot rootfs). Either one crashes the bootloader (DoS); patch 2 can
also copy adjacent heap memory into the loaded file (information disclosure).

  1/2 sqfs_find_inode()/sqfs_inode_size() walk the decompressed inode table
      using on-disk sizes with no check that the cursor stays inside the
      buffer -&gt; wild read / SEGV, e.g. from a simple "ls".
  2/2 sqfs_read_nest() uses the on-disk fragment offset as an unbounded
      source index into the fragment block -&gt; out-of-bounds heap read when
      loading a fragment-backed file.

Both were found by fuzzing the sandbox build (CONFIG_ASAN) of sqfsls/sqfsload
with mutated images. With the fixes, the crashing inputs are rejected
cleanly, 2000 fuzz iterations produce no further crashes, and the valid-image
path is unchanged.

These are distinct from the 2024 SquashFS CVE cluster (CVE-2024-57254..57259,
fixed in 2025.01-rc1) and from the sqfs_frag_lookup() fix (e365a269df5): the
earlier work added NULL checks at the callers and fixed the symlink-size and
fragment-table paths, but left these inode-table-walk and fragment-data
paths unbounded.

The two patches are independent and can be applied in either order.

Link: https://lore.kernel.org/r/20260612075424.83462-1-piyushthepal@gmail.com
</content>
</entry>
<entry>
<title>fs/squashfs: bound fragment offset/size in sqfs_read_nest()</title>
<updated>2026-08-28T14:55:57Z</updated>
<author>
<name>Piyush Paliwal</name>
<email>piyushthepal@gmail.com</email>
</author>
<published>2026-06-12T07:54:24Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/u-boot.git/commit/?id=923f05ed3e231c51f259bee6e2ac823bdaf1c566'/>
<id>urn:sha1:923f05ed3e231c51f259bee6e2ac823bdaf1c566</id>
<content type='text'>
When reading a fragment-backed file, sqfs_read_nest() copies the file
data out of the fragment block with:

  memcpy(buf + *actread, &amp;fragment_block[finfo.offset],
         finfo.size - *actread);

finfo.offset (the fragment's byte offset) and finfo.size come straight
from the on-disk inode and are never validated against the fragment
block length. Unlike the data-block loop above it, this path does not
clamp the source span, so a crafted inode makes the memcpy read past the
fragment buffer -&gt; out-of-bounds heap read. The leaked bytes are copied
into the user-visible load buffer (information disclosure) or fault.
This affects both the compressed (dest_len bytes) and the uncompressed
(table_size bytes) fragment cases.

Validate finfo.offset and the copy length against the available fragment
data before each memcpy and reject malformed inodes.

Found by fuzzing the sandbox (CONFIG_ASAN) sqfsload with mutated images:
before, SEGV in sqfs_read_nest() at the fragment memcpy; after, malformed
images are rejected and valid fragmented files still load correctly.

Fixes: 0008d8086649 ("fs/squashfs: fix reading of fragmented files")
Cc: stable@vger.kernel.org
Signed-off-by: Piyush Paliwal &lt;piyushthepal@gmail.com&gt;
Reviewed-by: Richard Genoud &lt;richard.genoud@bootlin.com&gt;
</content>
</entry>
<entry>
<title>fs/squashfs: bound the inode table walk in sqfs_find_inode()</title>
<updated>2026-08-28T14:55:57Z</updated>
<author>
<name>Piyush Paliwal</name>
<email>piyushthepal@gmail.com</email>
</author>
<published>2026-06-12T07:54:23Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/u-boot.git/commit/?id=73ada2f433a99fb2f443bb76268f5ab023b11868'/>
<id>urn:sha1:73ada2f433a99fb2f443bb76268f5ab023b11868</id>
<content type='text'>
sqfs_find_inode() walks the decompressed inode table advancing
"offset += sqfs_inode_size(base, ...)" with no check that offset stays
within the table (metablks_count * SQFS_METADATA_BLOCK_SIZE). All sizes
come from the on-disk image, including the unbounded extended-directory
(LDIR) index walk and the regular-file block-list term in
sqfs_inode_size(). A crafted image makes base run off the end of the
buffer -&gt; out-of-bounds read / SEGV, reachable simply by listing the
image (ls/sqfsls) or any operation that resolves a path.

The earlier fix 3fb1df1e5 ("squashfs: Check sqfs_find_inode() return
value") only added NULL checks at the call sites; it did not add the
missing internal bound, so the wild read still occurs before the
function can return. c8e929e5 fixed only the symlink case of
sqfs_inode_size(), leaving the LDIR index walk unbounded.

Thread the inode table size from sqfs_read_inode_table() through the
squashfs_dir_stream to sqfs_find_inode(), and:
 - reject an inode whose base header does not fit in the table;
 - pass the remaining byte count to sqfs_inode_size() and validate every
   variable-length read (LDIR index list, REG/LREG block list, symlink,
   device/ipc inodes) against it, with overflow-checked arithmetic;
 - reject an inode whose computed size leaves the table.

Found by fuzzing the sandbox (CONFIG_ASAN) sqfsls/sqfsload with mutated
images. Before: SEGV in sqfs_find_inode (sqfs_inode.c) and in
sqfs_inode_size() LDIR walk. After: malformed images are rejected
cleanly; 2000 fuzz iterations produce no crash and the valid-image path
is unchanged.

Fixes: c51006130370 ("fs/squashfs: new filesystem")
Cc: stable@vger.kernel.org
Signed-off-by: Piyush Paliwal &lt;piyushthepal@gmail.com&gt;
Reviewed-by: Richard Genoud &lt;richard.genoud@bootlin.com&gt;
</content>
</entry>
<entry>
<title>Merge patch series "fs/squashfs: fix directory table integer overflow"</title>
<updated>2026-08-27T21:05:06Z</updated>
<author>
<name>Tom Rini</name>
<email>trini@konsulko.com</email>
</author>
<published>2026-08-27T21:05:06Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/u-boot.git/commit/?id=658fc6aee95784139f070f9945cb3bc5da8d7d22'/>
<id>urn:sha1:658fc6aee95784139f070f9945cb3bc5da8d7d22</id>
<content type='text'>
Shahriyar Jalayeri &lt;shahriyar@byteray.co.uk&gt; 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/20260728-sqfs-oob-fix-v2-0-077d9f0e01c4@byteray.co.uk
</content>
</entry>
<entry>
<title>fs/squashfs: fix integer overflow in directory table allocation</title>
<updated>2026-08-27T21:01:02Z</updated>
<author>
<name>Shahriyar Jalayeri</name>
<email>shahriyar@byteray.co.uk</email>
</author>
<published>2026-07-28T06:55:39Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/u-boot.git/commit/?id=561ae28cb56a082cfa90c1c421c4955bc215470b'/>
<id>urn:sha1:561ae28cb56a082cfa90c1c421c4955bc215470b</id>
<content type='text'>
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 &gt;= 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 &lt;shahriyar@byteray.co.uk&gt;
Reviewed-by: Richard Genoud &lt;richard.genoud@bootlin.com&gt;
</content>
</entry>
<entry>
<title>fs/squashfs: bound the offset returned by sqfs_dir_offset()</title>
<updated>2026-08-27T21:00:03Z</updated>
<author>
<name>Pranav Rajendran</name>
<email>pranavkasthuri@gmail.com</email>
</author>
<published>2026-08-15T22:01:15Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/u-boot.git/commit/?id=e007b43a272edae8a63ad66f0151ceaf8cf003c1'/>
<id>urn:sha1:e007b43a272edae8a63ad66f0151ceaf8cf003c1</id>
<content type='text'>
Commit 57e0bb7bf00d ("fs/squashfs: add sqfs_dir_offset() error checks")
made sqfs_search_dir() reject negative returns from sqfs_dir_offset(),
but the positive range is still unbounded. Both parts of the returned
offset come from the image: 'offset' is a 16-bit inode field used
verbatim, and the matched metadata block index may be the last one in
m_list, in which case the returned block (j + 1) is one past the end
of the directory table.

The callers use the result to index dirs-&gt;dir_table[], which
sqfs_read_directory_table() allocates as m_count metadata blocks, and
then memcpy() a directory header out of it. A crafted image can
therefore read up to 64 KiB past the end of that allocation.

Reject an inode offset that cannot address a decompressed metadata
block, and verify that the resulting directory header lies entirely
within the directory table.

The existing 'offset &lt; 0' test is dropped: 'offset' is assigned from
get_unaligned_le16() and so is never negative, meaning the test never
fired. The new upper bound covers what it was meant to catch.

Fixes: c51006130370 ("fs/squashfs: new filesystem")
Signed-off-by: Pranav Rajendran &lt;pranavkasthuri@gmail.com&gt;
Reviewed-by: Richard Genoud &lt;richard.genoud@bootlin.com&gt;
</content>
</entry>
<entry>
<title>fs/squashfs: bound fragment table accesses in sqfs_frag_lookup()</title>
<updated>2026-08-27T21:00:03Z</updated>
<author>
<name>Pranav Rajendran</name>
<email>pranavkasthuri@gmail.com</email>
</author>
<published>2026-08-15T22:01:14Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/u-boot.git/commit/?id=fc557ef9fe116b3245265629cf1d3ab4ac7a480c'/>
<id>urn:sha1:fc557ef9fe116b3245265629cf1d3ab4ac7a480c</id>
<content type='text'>
sqfs_frag_lookup() validates its fragment index only against
sblk-&gt;fragments, which is read from the image superblock and is
therefore under the control of whoever supplies the image. Every
buffer access derived from that index is then made without checking
it against the size of the buffer actually read from the device:

 - the fragment index table entry at 'table_offset + block *
   sizeof(u64)' can be read past the end of 'table', as 'block' is
   inode_fragment_index / SQFS_MAX_ENTRIES and has no upper bound;

 - the metadata block header and payload are read from
   'metadata_buffer' at 'table_offset', but that buffer is sized from
   start_block, which comes from the unvalidated index table entry
   above. A start_block just below sblk-&gt;fragment_table_start yields a
   single-block buffer while SQFS_METADATA_SIZE(header) may be up to
   SQFS_METADATA_BLOCK_SIZE, so both the decompression source and the
   memcpy() source can run past the end of the buffer;

 - 'entries' is allocated with SQFS_METADATA_BLOCK_SIZE bytes but only
   partially filled, so entries[offset] can read uninitialised heap
   memory when the metadata block holds fewer than offset + 1 entries.

Compute the size of both buffers explicitly, rejecting the
multiplication overflow the way sqfs_read_directory_table() already
does, and check each access against it. Also track how much of
'entries' was populated and reject an index beyond that.

A crafted SquashFS image can trigger all three cases, either crashing
U-Boot or feeding adjacent heap contents into the fragment entry that
the following data read is based on.

Fixes: c51006130370 ("fs/squashfs: new filesystem")
Signed-off-by: Pranav Rajendran &lt;pranavkasthuri@gmail.com&gt;
Reviewed-by: Richard Genoud &lt;richard.genoud@bootlin.com&gt;
</content>
</entry>
<entry>
<title>fs: btrfs: deduplicate the inode size lookup</title>
<updated>2026-08-10T18:38:57Z</updated>
<author>
<name>Cole Munz</name>
<email>Munzzyy1@proton.me</email>
</author>
<published>2026-08-02T09:35:26Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/u-boot.git/commit/?id=a11f8659f451c5601bac6fdf5b48594d347db38d'/>
<id>urn:sha1:a11f8659f451c5601bac6fdf5b48594d347db38d</id>
<content type='text'>
btrfs_readdir() and btrfs_size() both open code the same search for an
inode item to read its size field. Move it into one helper.

Signed-off-by: Cole Munz &lt;Munzzyy1@proton.me&gt;
Reviewed-by: Qu Wenruo &lt;wqu@suse.com&gt;
</content>
</entry>
<entry>
<title>fs: btrfs: release the path when btrfs_search_slot() fails</title>
<updated>2026-08-10T18:38:57Z</updated>
<author>
<name>Cole Munz</name>
<email>Munzzyy1@proton.me</email>
</author>
<published>2026-08-02T09:35:22Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/u-boot.git/commit/?id=1a5c8af2d4e4b4029739eb8787ce259d74977dfd'/>
<id>urn:sha1:1a5c8af2d4e4b4029739eb8787ce259d74977dfd</id>
<content type='text'>
The U-Boot copy of btrfs_search_slot() returns on error with the nodes
it has descended through still attached to the path. The kernel one
releases the path on any error unless p-&gt;skip_release_on_error is set,
and callers written against that convention treat a failed search as
owning nothing. btrfs_size() is one: it returns straight away on a
search error and never reaches its btrfs_release_path() call, so the
attached extent buffer references leak.

Route both error exits through a release of the path. The error
returns of read_node_slot() carry no extra reference, so the path is
the only thing to clean up.

Suggested-by: Qu Wenruo &lt;quwenruo.btrfs@gmx.com&gt;
Signed-off-by: Cole Munz &lt;Munzzyy1@proton.me&gt;
Reviewed-by: Qu Wenruo &lt;wqu@suse.com&gt;
</content>
</entry>
<entry>
<title>fs: btrfs: report file sizes from readdir</title>
<updated>2026-08-10T18:38:57Z</updated>
<author>
<name>Cole Munz</name>
<email>Munzzyy1@proton.me</email>
</author>
<published>2026-08-02T09:35:19Z</published>
<link rel='alternate' type='text/html' href='http://cgit.235523.xyz/u-boot.git/commit/?id=1cf825afd0d7ebb4857002833658574efbef6626'/>
<id>urn:sha1:1cf825afd0d7ebb4857002833658574efbef6626</id>
<content type='text'>
btrfs_readdir() zeroes the dirent and fills in only the name and the
type, so dent-&gt;size stays 0 and every file is listed as zero bytes:

  =&gt; ls host 0 /
          0   f_192k.bin
          0   small_3k.bin

Reads themselves are fine, since btrfs_read() takes the size from
btrfs_size(), which does its own inode item lookup. It affects EFI
too: dir_read() in lib/efi_loader/efi_file.c copies dent-&gt;size into
both file_size and physical_size, so an EFI application enumerating a
directory on btrfs sees every file as empty, which is the generic-code
path Alexey's readdir series moves btrfs onto.

The custom listing that fs_ls_generic() replaced looked the inode item
up and printed the real size, and every other filesystem in the tree
fills dent-&gt;size in its own readdir: ext4fs.c:327, exfat io.c:805,
erofs fs.c:186, squashfs sqfs.c:1095 and fat.c:1555.

btrfs_next_dir_entry() already has the dir item mapped, so read the
key it points at while we are there and hand it back to the caller,
and use that to reach the inode item. A subvolume entry points at a
root item instead and has no size of its own, so leave that one at 0.

  =&gt; ls host 0 /
     196608   f_192k.bin
       3000   small_3k.bin

Fixes: 31cf3f177823 ("fs: btrfs: use fs_ls_generic() and drop custom implementation")
Signed-off-by: Cole Munz &lt;Munzzyy1@proton.me&gt;
Reviewed-by: Qu Wenruo &lt;wqu@suse.com&gt;
</content>
</entry>
</feed>
