Files
Hauke Mehrtens e056c32ed0 mtd: validate trx->len in trx_fixup()
trx_fixup() computed the CRC32 range from the on-flash TRX header
without validating it:

    scan = ptr + offsetof(struct trx_header, flag_version);
    trx->crc32 = crc32buf(scan, trx->len - (scan - ptr));

trx->len is read from the mmap()ed partition and is only sanity checked
in trx_check(), which is a separate entry point. A trx->len larger than
the partition therefore makes crc32buf() walk that many bytes past the
end of the mapping and crash mtd with SIGSEGV.

The mirror case of a trx->len below the 12 byte offset does not overread
in practice: crc32buf() takes a size_t but passes it to crc32(), which
takes an int len and loops on "while (--len >= 0)". The wrapped value
truncates to a negative int, so the loop body never runs and a zero
length CRC32 is written instead. Values at or above 0x8000000c truncate
the same way. Only the range from sizeof(struct trx_header) to roughly
0x8000000b stays positive through the truncation and reads out of
bounds, which is exactly the range a plausible bad length falls into.

Bound trx->len on both sides before computing the range, using the same
lower limit trx_check() already applies. Both comparisons are unsigned,
so the wrapping cases are rejected as well.

trx_fixup() runs as root on the contents of the flash, so this is a
robustness fix rather than a privilege boundary: it is reachable through
"mtd jffs2write" and the jffs2_replaced path of "mtd write", not through
"mtd fixtrx", which uses mtd_fixtrx() and derives its length from
erasesize instead. The practical benefit is not crashing on a truncated
or corrupted header during sysupgrade.

Link: https://github.com/openwrt/openwrt/security/advisories/GHSA-wch3-f5gc-mw2h
Reported-by: @tonoyx91
Reported-by: @0xROI
Fixes: bbd9eb4669 ("clean up mtd, fix up trx header when integrating jffs2 data on broadcom devices")
Assisted-by: Claude:claude-opus-5
Link: https://github.com/openwrt/openwrt/pull/25284
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
2026-09-26 21:26:29 +02:00

53 lines
1.1 KiB
Makefile

#
# Copyright (C) 2006-2012 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=mtd
PKG_RELEASE:=29
PKG_BUILD_DIR := $(KERNEL_BUILD_DIR)/$(PKG_NAME)
STAMP_PREPARED := $(STAMP_PREPARED)_$(call confvar,CONFIG_MTD_REDBOOT_PARTS)
PKG_LICENSE:=GPL-2.0+
PKG_LICENSE_FILES:=
PKG_FLAGS:=nonshared
PKG_BUILD_FLAGS:=lto
include $(INCLUDE_DIR)/package.mk
define Package/mtd
SECTION:=utils
CATEGORY:=Base system
DEPENDS:=+libubox
TITLE:=Update utility for trx firmware images
endef
define Package/mtd/description
This package contains an utility useful to upgrade from other firmware or
older OpenWrt releases.
endef
target=$(firstword $(subst -, ,$(BOARD)))
MAKE_FLAGS += TARGET="$(target)"
TARGET_CFLAGS += -Dtarget_$(target)=1 -Wall
ifdef CONFIG_MTD_REDBOOT_PARTS
MAKE_FLAGS += FIS_SUPPORT=1
TARGET_CFLAGS += -DFIS_SUPPORT=1
endif
define Package/mtd/install
$(INSTALL_DIR) $(1)/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/mtd $(1)/sbin/
endef
$(eval $(call BuildPackage,mtd))