From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-qv1-f53.google.com (mail-qv1-f53.google.com [209.85.219.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5BAA2283FC8 for ; Wed, 15 Apr 2026 12:48:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.53 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776257316; cv=none; b=N6RVR7eXeyRoMLVEy+LRKmuU8EY8av5mORM8QpTp1vCaajhiMz50YKZ357WgWB5M8evRDJQmK/aNt6UGKFCxD8fWU09VF9JtGu0nUa1LfpgjbRO1iZQHsJMlWhcVDFNoAylLE7vluzHWm43NW9rnoqftY2AHD0EUlWJWmlkUDdA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776257316; c=relaxed/simple; bh=Pv0lqVw39ceozF1TiendXpliruHOKPPL1EIFk5Uyn/M=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version:Content-Type; b=mjwPUgpCe7zDscRmCwADXOWWYuMVhMYkbE5EIw5qmSs/zGxl2+ZlGTjFBq9j9DPALJixyE3V5ctUxFT5ziZpHIeaGYqBP7Ly3xRLO7K1OzxUVDjKYhcBuMxGmrA4QgZLqHZaRfLl1lkPGmjiql77RavKKSI7p5s/J+VTlGwYfls= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=WGhTOByx; arc=none smtp.client-ip=209.85.219.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="WGhTOByx" Received: by mail-qv1-f53.google.com with SMTP id 6a1803df08f44-8a068db9989so63835746d6.0 for ; Wed, 15 Apr 2026 05:48:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776257308; x=1776862108; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=nfWIOLjASEqsTxbYRvhI/OUYGKeRm/Dc+ijgJBGHXBM=; b=WGhTOByxSlYNUA1GRuvB3jQv3Vqt1QnLrfeNCaPgxY4OpFmVwKK5aA+t8RzE0jM0RE AUyc5nohPP5hg/uhPAiiIGTnSE6i8/XzElZrwYlKuM90paRz2dV7n09aKrXmucsoE56/ sV3L3eTeFHZgeMXqrWun+x0v/0ySn7GIy1Ua29HZlqqp8zWoDYIb5dGGxzAjI29+ISOQ oHUzIwpPuu/okeg7+BOALHIZdQKM3+xphzJrqU7t0LFJVWMKDGXB23rE4Rx2JgKKGApS pBMgwxI8yqHC4nv0JNNJE4+jLKs8DF035JDuYWx6gu6LiauLDdoZh3zF7CtvVm2cP8J4 oCBQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776257308; x=1776862108; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=nfWIOLjASEqsTxbYRvhI/OUYGKeRm/Dc+ijgJBGHXBM=; b=guyVLLwKlwGoEGscGRLwCSX4CBE2/anxngUSfi1fAigLqfCuen2y2jBLnkl9AokW/E aDm1B0Jt4DqgSlcLckiSvuWxrVX+pnNxcdnyZhW17/w/H/0KpBeYDNh2NsugWUY2+nSj TWn+vNVFKVZpllvYPzNYy+4AI8AWDo1rpDOFYS1tYMOCSLJZqsTth8RmIbzdMPeXWQnY ogiA8l08KPVnHz4srVVTiZkm3lNN+YzNCL+oSShNqXaeje5spkpOpVfAhRvCnO0Go1Ks ssCdn2CFhNgxEF+ptFCJSzdnIFvAvXvCeSTz9t4ry+NFwiykhWrpaKgjXhSphEl2T7Zw YmNQ== X-Forwarded-Encrypted: i=1; AFNElJ85T7VPTirlvrRNapF8/F+XVotD1yiJ5Gy5X2g9+wQ+kqM9d2z6f2erGz+5V6wFfy1hxVT8tC1NEHT8TGc=@vger.kernel.org X-Gm-Message-State: AOJu0YwW3Vne6POSJF/AOwWifAG+yPTgg7BY/YGoav/g4SN/Diol6uXK 1dTV7YfyXvhIIiHHGwlu6yuRis+WExfVuGw7dswlGya+z7VNouQdgTImPm35/g== X-Gm-Gg: AeBDieu5mZiS3bg9VXmjZF9/OuPCZrSFwg3/AUHt6ChtcAosbfyaiWIOFHpDKPeGFuN lXzV4z+Cimwl4PP1HjH6By2y95ghuyJtcV5/qs9JVCQBRec3mZOKMq/nrGX2mXMLmjmpGBO/32r fWq5q1IaKi10FBIwhmgHeKA9ltUxmVn8b4LdfedGFt4LXG3fiSE0jcadno3KeIJOipxDsbsm8Cc GeSGl03i31sFCPCinEupNvXZXZ8tsVPYfA7+gGObZvElfeg+rUYkCzBeVeUybAjE7plrmq7zSQw lhgKXCcpyIdSwXBUCrAC7Sqs5xQguXJcZdl7JwRXLFSKWT5Bgq1rru4SkbcaM3rj6Q7BjPXAxXT 18BsPB46nmvOFu+Iijuuz/f0lBcpmEKOkPMtA4CZVfQ1vfSKfVobGzqFAamNuqNDASNzUD+5CMj 3VibMvgC+5WTWHFmyL/ond/yGu8ZZ8pn1CH8GfUSKFCDXxI8DeJTYzyvSNUSMLC1xVIIWLQHefs C40RJEPjB/649hLP9ZlUE+6iylRKDY450lFV73YxyjvLkKYMn7ujQ== X-Received: by 2002:a05:6214:43c8:b0:8a1:2c95:5756 with SMTP id 6a1803df08f44-8ac7453ee8bmr355390306d6.6.1776257307849; Wed, 15 Apr 2026 05:48:27 -0700 (PDT) Received: from server0.tail6e7dd.ts.net (c-68-48-65-54.hsd1.mi.comcast.net. [68.48.65.54]) by smtp.gmail.com with ESMTPSA id 6a1803df08f44-8ae6ceb891csm10614016d6.48.2026.04.15.05.48.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 15 Apr 2026 05:48:26 -0700 (PDT) From: Michael Bommarito To: linux-mtd@lists.infradead.org, David Woodhouse , Richard Weinberger Cc: Zhihao Cheng , Artem Sadovnikov , Kees Cook , linux-kernel@vger.kernel.org Subject: [PATCH 0/2] jffs2: bound summary reads on crafted flash Date: Wed, 15 Apr 2026 08:48:11 -0400 Message-ID: <20260415124813.246588-1-michael.bommarito@gmail.com> X-Mailer: git-send-email 2.53.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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