mirror of
https://github.com/openwrt/openwrt.git
synced 2026-10-13 00:17:02 +04:00
The "name=value\0 ... \0\0" walk over the mmap()ed nvram used strchr()
and strlen() without a bound, so an nvram without the terminating
double NUL made it run past the end of the mapping.
Search with memchr() up to the length from the nvram header, or up to
the end of the mapping when that length does not fit, so a broken
header is still readable. A variable that is not terminated in this
area ends the parsing.
Map a regular file, like the /tmp staging file, only as far as it is
backed, rounded down to 4 bytes for the padding in nvram_commit(),
instead of the partition size which raised SIGBUS. Only search the
start of a mapping smaller than NVRAM_MIN_SPACE for the magic instead
of underflowing the loop boundary; bcm47xxpart creates such nvram
partitions on flashes with 4 KiB erase blocks.
"nvram info" clamps the header length before the CRC8, it read beyond
the mapping or underflowed into a 4 GB read before.
This is reachable with a crafted nvram partition or staging file, on
bcm47xx the nvram partition is also parsed while booting.
Reported by @tonoyx91 and @0xROI.
Link: https://github.com/openwrt/openwrt/security/advisories/GHSA-5m25-qmhm-crr4
Fixes: 400c1a7fbf ("Add unvram, a nvram manipulation tool suitable for brcm-2.4 and bcm47xx platforms")
Assisted-by: Claude:claude-opus-5
Link: https://github.com/openwrt/openwrt/pull/25240
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>