The Zephyr ext2 filesystem driver (subsys/fs/ext2) trusted the on-disk directory entry fields dereclen and denamelen when walking a directory block. ext2fetchdirentry() guarded only with denamelen > EXT2MAXFILENAME, but denamelen is a uint8t and EXT2MAXFILENAME is 255, so the check is always false; the function then memcpy'd up to 255 name bytes and the lookup/readdir paths advanced traversal by an unvalidated dereclen. Each directory block is read into a blocksize-sized slab buffer, and blockoff can be driven near the block end by preceding entries' reclen, so the 8-byte header read and the subsequent name memcpy can read up to ~263 bytes past the end of the block buffer into adjacent heap/slab memory. On the readdir path those bytes are returned to the caller in fsdirent.name, leaking adjacent kernel heap memory; a dereclen of 0 also causes a zero-progress infinite loop (denial of service), and the unlink path's memmove(de, next, nextreclen) over unvalidated records is an additional OOB read/write source. The defect is reached by any path-based operation (open, stat, unlink, rename, mkdir) or directory listing on a mounted ext2 volume, so a crafted or corrupted ext2 image on attacker-supplied storage (SD card, USB mass storage, or otherwise mounted image) triggers it. Affected: Zephyr ext2 from its introduction in v3.5.0 through v4.4.0. The fix validates reclen and namelen in the parser and rejects entries whose header does not fit the remaining block or whose reclen crosses the block boundary in every traversal caller.
The Zephyr ext2 filesystem driver fails to validate the slogblocksize field of the on-disk superblock when mounting a filesystem. ext2verifydisksuperblock() in subsys/fs/ext2/ext2impl.c checks the magic number, revision, inode size and group counts, but never bounds slogblocksize. On a successful verify, subsys/fs/ext2/ext2ops.c computes fs->blocksize = 1024 << superblock.slogblocksize from this attacker-controlled uint32t, so a crafted value either overflows the shift (undefined behaviour) or yields a block size far larger than CONFIGEXT2MAXBLOCKSIZE.
That block size is then passed to kmemslabinit() by ext2initblocksslab() to carve CONFIGEXT2MAXBLOCKCOUNT blocks out of the fixed static buffer ext2blockmemorybuffer, whose size is CONFIGEXT2MAXBLOCKCOUNT CONFIGEXT2MAXBLOCKSIZE. kmemslabinit() does not verify that the requested blocks fit the buffer, and the ext2 wrapper discards its return value, so the slab is laid out past the end of the static buffer. The mount immediately reads block-group, bitmap and inode blocks of fs->blocksize bytes each into these slab blocks, producing an out-of-bounds write into adjacent static memory on the first block read.
The entire path is gated only by data read from the mounted image, making this reachable by any attacker who can present a crafted ext2 image to a device that mounts it (for example a removable SD card or storage medium). Because the ext2 driver runs in kernel mode, supplying image bytes yields a supervisor-mode memory-corruption primitive, with impact ranging from denial of service to potential code execution.
The fix rejects slogblocksize values that overflow the shift (greater than 11) or that produce a block size exceeding CONFIGEXT2MAXBLOCKSIZE, so the block slab can no longer be initialized larger than its backing buffer.
The Zephyr ext2 filesystem driver validates the on-disk block bitmap in ext2initfs() (subsys/fs/ext2/ext2impl.c) by passing fsblocks = sblockscount - sfirstdatablock to ext2bitmapcountset(). That helper (subsys/fs/ext2/ext2bitmap.c) treats its argument as a number of bits and reads one bitmap byte per eight bits, but the bitmap buffer (BGROUPBLOCKBITMAP) is a single fetched block of only fs->blocksize bytes (capacity fs->blocksize 8 bits). sblockscount and sfirstdatablock are taken verbatim from the superblock and were never bounded against this single-group capacity; ext2verifydisksuperblock() checks the magic, revision, and block-size shift but not the block count.
A crafted ext2 image with an oversized sblockscount (up to ~4 billion, against a maximum 4096-byte block / 32768-bit bitmap) makes ext2bitmapcountset() scan roughly 512 MB of memory past the bitmap block — a large out-of-bounds read of the static block slab and adjacent memory.
The defect is reached during mount: ext2initfs() is invoked from ext2mount() (subsys/fs/ext2/ext2ops.c), the registered .mount operation. Any path that mounts an attacker-supplied ext2 image (removable media, a disk/flash partition, or a downloaded image) triggers it. The kernel-privileged parser operates on attacker-controlled data, so the bug is exploitable wherever untrusted ext2 media can be mounted.
Impact is an out-of-bounds read only: the resulting bit count is compared internally and the mount is rejected, so no attacker-controlled bytes are returned (not a useful information leak). The ~512 MB over-read will almost certainly cross an unmapped or MPU-protected boundary and fault, crashing the system — a denial of service triggered by mounting a single malformed image. The fix rejects any image whose fsblocks exceeds fs->blocksize 8 before the scan.
The Zephyr ext2 filesystem driver fails to validate the slogblocksize field of the on-disk superblock when mounting a filesystem. ext2verifydisksuperblock() in subsys/fs/ext2/ext2impl.c checks the magic number, revision, inode size and group counts, but never bounds slogblocksize. On a successful verify, subsys/fs/ext2/ext2ops.c computes fs->blocksize = 1024 << superblock.slogblocksize from this attacker-controlled uint32t, so a crafted value either overflows the shift (undefined behaviour) or yields a block size far larger than CONFIGEXT2MAXBLOCKSIZE.
That block size is then passed to kmemslabinit() by ext2initblocksslab() to carve CONFIGEXT2MAXBLOCKCOUNT blocks out of the fixed static buffer ext2blockmemorybuffer, whose size is CONFIGEXT2MAXBLOCKCOUNT CONFIGEXT2MAXBLOCKSIZE. kmemslabinit() does not verify that the requested blocks fit the buffer, and the ext2 wrapper discards its return value, so the slab is laid out past the end of the static buffer. The mount immediately reads block-group, bitmap and inode blocks of fs->blocksize bytes each into these slab blocks, producing an out-of-bounds write into adjacent static memory on the first block read.
The entire path is gated only by data read from the mounted image, making this reachable by any attacker who can present a crafted ext2 image to a device that mounts it (for example a removable SD card or storage medium). Because the ext2 driver runs in kernel mode, supplying image bytes yields a supervisor-mode memory-corruption primitive, with impact ranging from denial of service to potential code execution.
The fix rejects slogblocksize values that overflow the shift (greater than 11) or that produce a block size exceeding CONFIGEXT2MAXBLOCKSIZE, so the block slab can no longer be initialized larger than its backing buffer.