public inbox for linux-mtd@lists.infradead.org
 help / color / mirror / Atom feed
* [PATCH 0/2] jffs2: bound summary reads on crafted flash
@ 2026-04-15 12:48 Michael Bommarito
  2026-04-15 12:48 ` [PATCH 1/2] jffs2: reject truncated summary node before header validation Michael Bommarito
  2026-04-15 12:48 ` [PATCH 2/2] jffs2: bound summary entry walks against the payload Michael Bommarito
  0 siblings, 2 replies; 3+ messages in thread
From: Michael Bommarito @ 2026-04-15 12:48 UTC (permalink / raw)
  To: linux-mtd, David Woodhouse, Richard Weinberger
  Cc: Zhihao Cheng, Artem Sadovnikov, Kees Cook, linux-kernel

Hi,

Two mount-time out-of-bounds reads in fs/jffs2/summary.c that are
reachable when the kernel mounts a crafted JFFS2 flash image.  Both
reproduced on v7.0-rc7 under UML with CONFIG_KASAN=y and
CONFIG_MTD_BLOCK2MTD=y; pre-fix each oopses in
jffs2_sum_scan_sumnode, post-fix the same images are rejected with a
warning and the scanner falls back to the full scan path.

1/2 -- jffs2_sum_scan_sumnode() computes

         crc = crc32(0, summary->sum,
                     sumsize - sizeof(struct jffs2_raw_summary));

       If a crafted on-flash jffs2_sum_marker.offset drives sumsize
       below sizeof(struct jffs2_raw_summary) (= 32), the subtraction
       underflows in size_t and crc32() walks ~16 EiB.  The earlier
       header reads of summary->totlen / ->hdr_crc / ->node_crc are
       OOB for the same class of sumsize values.  Bound sumsize at
       JFFS2_SUMMARY_FRAME_SIZE (header + marker = 40) which is the
       minimum frame the writer at jffs2_sum_write_sumnode() emits.

       KASAN evidence:

         BUG: KASAN: slab-out-of-bounds in
              jffs2_sum_scan_sumnode+0x131/0x1611
         Read of size 4 at addr 00000000621fb004 by task mount/31
         Located 4 bytes to the right of 4096-byte region

2/2 -- jffs2_sum_process_sum_data() iterates summary->sum_num times
       with no bounds check on the remaining payload.  Crafted
       sum_num > (actual entries) walks sp off the summary buffer;
       nodetype is then read from adjacent slab memory, and if those
       bytes decode as one of the known case labels the handler
       calls sum_link_node_ref() with offset/totlen pulled from the
       OOB bytes.  Pass sumsize into the helper and bound sp before
       every nodetype read and every type-specific field access.

       KASAN evidence (patch 1 applied so the bug is reached):

         BUG: KASAN: slab-out-of-bounds in
              jffs2_sum_scan_sumnode+0x6bd/0x16bf
         Read of size 2 at addr 00000000621fb000 by task mount/31
         Located 0 bytes to the right of 4096-byte region

       A matching sum_num=1 image (same bytes, honest sum_num) does
       not splat.

Impact:

  Mount-time only, CAP_SYS_ADMIN required to attach the MTD and
  call mount(2).  Not reachable from unprivileged users, user
  namespaces, FUSE, or network.  Relevant practically on embedded
  devices that auto-mount JFFS2 on boot when the flash is writable
  out-of-band.

  1/2 is an OOB read / DoS on mount.

  2/2 is not just an OOB read: the type-specific handlers run past
  the buffer boundary before sp is bounded, so corrupted in-memory
  jeb state can persist past the faulting iteration rather than
  cleanly oopsing.  Closing the bound prevents that sequence.  No
  controlled kernel write, no RCE primitive in evidence.

Reproduction artefacts (craft scripts, UML init, pre/post KASAN
logs) are on the reporter side on request.

Thanks,
Mike

Michael Bommarito (2):
  jffs2: reject truncated summary node before header validation
  jffs2: bound summary entry walks against the payload

 fs/jffs2/summary.c | 44 +++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 41 insertions(+), 3 deletions(-)

-- 
2.53.0


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-04-15 12:48 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-15 12:48 [PATCH 0/2] jffs2: bound summary reads on crafted flash Michael Bommarito
2026-04-15 12:48 ` [PATCH 1/2] jffs2: reject truncated summary node before header validation Michael Bommarito
2026-04-15 12:48 ` [PATCH 2/2] jffs2: bound summary entry walks against the payload Michael Bommarito

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox