From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AED7947DD5C; Mon, 20 Apr 2026 13:31:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776691866; cv=none; b=ci9f8yexXjpY2dhOjCK67+Xb3GqQ8gwCFF4H0igv5WRL+r7ab08AqoE8tRJp9fzb7+hDFEXXB90P/IsrMsN+AyFVE1TNQHPsngSCUUgBkrsFDI8PTu+rk8P2tYnSKt0F4UMz2Bk4SZvHBlygjwWc1AGUYFdNQTL//2Xva3ydeAU= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776691866; c=relaxed/simple; bh=LQn/llo0rrUEvfsTY1FngiGPnJbrv9C4JZ20atkOjDw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=AzZCWVghpKVOxpCfq+KeEdNYjg45kGRTZiuiwPH9QCJmN5KmSwqb3ouJ8sMEIr89jYJJEihaBQNg9m5YwzUJA6Tgh9SEFkW9s4w2ZaupRW8FEG+s/oieREedgJ59yyneKa7+9zZOPVF4bFsgeS4ojXSnIllna8+UayNgyvuZOZQ= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Trb6v34Q; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Trb6v34Q" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 142B9C4AF09; Mon, 20 Apr 2026 13:31:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1776691866; bh=LQn/llo0rrUEvfsTY1FngiGPnJbrv9C4JZ20atkOjDw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Trb6v34QelxxEB0eX75MYNDku7JO+1yCDcAVeaZi6MOA4HmdaNgaKeRaa3GP9I9Rh yl202cr91dcQPdOZBTuVn/SgsbafSmVRuBTyeY7T3IbmFHV7jAOAxM0NiYHPJgXCou XiQHvxByHBuxTXbD7k9UOdjPoWbApgN5mSyO6ovkWENgh5mp0BMnUB3H/JvTgx8hbF IlvBu0Adsys8/wI5AmJNP81tgca4urNy1hPYU9JAr3mxTRlWfllZi9OYatrSZ42gV7 R5jwKtNmHemC++A5rXQKu08NaNjyFrivPBssLpwKC9HP8HPhdAb9wvcqY2xVBIYu+S 5ZZFQ7TktsVtQ== From: Sasha Levin To: patches@lists.linux.dev, stable@vger.kernel.org Cc: Mashiro Chen , Joerg Reuter , Jakub Kicinski , Sasha Levin , andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com, pabeni@redhat.com, linux-hams@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH AUTOSEL 7.0-5.10] net: hamradio: scc: validate bufsize in SIOCSCCSMEM ioctl Date: Mon, 20 Apr 2026 09:20:34 -0400 Message-ID: <20260420132314.1023554-240-sashal@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260420132314.1023554-1-sashal@kernel.org> References: <20260420132314.1023554-1-sashal@kernel.org> Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore X-stable-base: Linux 7.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Mashiro Chen [ Upstream commit 8263e484d6622464ec72a5ad563f62492d84fa54 ] The SIOCSCCSMEM ioctl copies a scc_mem_config from user space and assigns its bufsize field directly to scc->stat.bufsize without any range validation: scc->stat.bufsize = memcfg.bufsize; If a privileged user (CAP_SYS_RAWIO) sets bufsize to 0, the receive interrupt handler later calls dev_alloc_skb(0) and immediately writes a KISS type byte via skb_put_u8() into a zero-capacity socket buffer, corrupting the adjacent skb_shared_info region. Reject bufsize values smaller than 16; this is large enough to hold at least one KISS header byte plus useful data. Signed-off-by: Mashiro Chen Acked-by: Joerg Reuter Link: https://patch.msgid.link/20260409024927.24397-3-mashiro.chen@mailbox.org Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- LLM Generated explanations, may be completely bogus: All the data is gathered. Let me compile the complete analysis. --- ## PHASE 1: COMMIT MESSAGE FORENSICS **Step 1.1: Subject Line** - Subsystem: `net: hamradio: scc` - Action verb: "validate" — indicates adding missing input validation, i.e., fixing missing bounds checking - Summary: Add missing bounds check on `bufsize` parameter from userspace ioctl **Step 1.2: Tags** - `Signed-off-by: Mashiro Chen` — patch author - `Acked-by: Joerg Reuter ` — this is the **original driver author** (copyright holder since 1993, confirmed in file header). Strong endorsement. - `Link:` to patch.msgid.link — standard netdev submission - `Signed-off-by: Jakub Kicinski` — netdev maintainer applied it. Strong trust signal. **Step 1.3: Commit Body** - Bug: `SIOCSCCSMEM` ioctl copies `bufsize` from userspace without validation - Symptom: If `bufsize` is set to 0, `dev_alloc_skb(0)` creates a zero- capacity skb, then `skb_put_u8()` writes past the buffer, corrupting `skb_shared_info` - This is a **memory corruption bug** triggered via ioctl (requires CAP_SYS_RAWIO) - Fix: reject `bufsize < 16` **Step 1.4: Hidden Bug Fix?** Not hidden — this is an explicit, well-described input validation bug fix preventing memory corruption. ## PHASE 2: DIFF ANALYSIS **Step 2.1: Inventory** - 1 file changed: `drivers/net/hamradio/scc.c` - 2 lines added, 0 lines removed - Function: `scc_net_siocdevprivate()` **Step 2.2: Code Flow** - Before: `memcfg.bufsize` assigned directly to `scc->stat.bufsize` after `copy_from_user`, no validation - After: `memcfg.bufsize < 16` returns `-EINVAL` before assignment **Step 2.3: Bug Mechanism** Category: **Buffer overflow / out-of-bounds write**. Setting `bufsize=0` causes `dev_alloc_skb(0)` in `scc_rxint()`, then `skb_put_u8()` writes 1 byte into a zero-capacity buffer, corrupting adjacent `skb_shared_info`. **Step 2.4: Fix Quality** - Obviously correct: 2-line bounds check before assignment - Minimal and surgical — cannot introduce a regression - No side effects, no locking changes, no API changes ## PHASE 3: GIT HISTORY INVESTIGATION **Step 3.1: Blame** The buggy code (line 1912: `scc->stat.bufsize = memcfg.bufsize`) traces to `^1da177e4c3f41` (Linus Torvalds, 2005-04-16) — this is the initial Linux git import. The bug has existed since the **very beginning of the kernel source tree**. **Step 3.2: Fixes tag** No explicit `Fixes:` tag (expected — this is why it needs manual review). The buggy code predates git history. **Step 3.3: File history** Changes since v6.6 are only treewide renames (`timer_container_of`, `timer_delete_sync`, `irq_get_nr_irqs`). The SIOCSCCSMEM handler and `scc_rxint()` are completely untouched. **Step 3.5: Dependencies** None. The fix is self-contained — a simple bounds check addition. ## PHASE 4: MAILING LIST Lore is protected by anti-scraping measures and couldn't be fetched directly. However: - The patch was **Acked-by the original driver author** Joerg Reuter - It was applied by **netdev maintainer Jakub Kicinski** - It's patch 3 of a series (from message-id), but the fix is completely standalone ## PHASE 5: CODE SEMANTIC ANALYSIS **Step 5.1: Functions modified** `scc_net_siocdevprivate()` — the ioctl handler **Step 5.2: Consumer of `bufsize`** `scc_rxint()` (line 535) uses `scc->stat.bufsize` as the argument to `dev_alloc_skb()`. This is an **interrupt handler** — called on every received character from the Z8530 chip. When `bufsize=0`: 1. `dev_alloc_skb(0)` succeeds (returns a valid skb with 0 data capacity) 2. `skb_put_u8(skb, 0)` at line 546 writes 1 byte past the data area into `skb_shared_info` 3. This is **memory corruption in interrupt context** **Step 5.4: Reachability** The ioctl requires `CAP_SYS_RAWIO`. The corruption path is: ioctl sets bufsize → hardware interrupt fires → `scc_rxint()` → `dev_alloc_skb(0)` → `skb_put_u8` overflows. ## PHASE 6: STABLE TREE ANALYSIS **Step 6.1: Code exists in all stable trees** Verified: the identical vulnerable code exists in v5.15, v6.1, and v6.6. The buggy code dates to the initial kernel. **Step 6.2: Clean apply** The surrounding code is identical in v6.1 and v6.6 (verified). The 2-line addition will apply cleanly to all active stable trees. ## PHASE 7: SUBSYSTEM CONTEXT - Subsystem: `drivers/net/hamradio` — networking driver (ham radio Z8530) - Criticality: PERIPHERAL (niche hardware), but the bug is a **memory corruption**, which elevates priority regardless of driver popularity ## PHASE 8: IMPACT AND RISK ASSESSMENT **Step 8.1: Affected users** — Users of Z8530-based ham radio hardware (niche, but real) **Step 8.2: Trigger** — Requires `CAP_SYS_RAWIO` to set the bad bufsize via ioctl, then hardware interrupt triggers corruption. Privileged user action. **Step 8.3: Severity** — **HIGH**: Memory corruption in interrupt context. Corrupting `skb_shared_info` can lead to unpredictable behavior including crashes, further memory corruption, or potential exploitation. **Step 8.4: Risk-Benefit** - Benefit: Prevents memory corruption from invalid ioctl input - Risk: Near zero — 2 lines of obvious bounds checking - Ratio: Excellent — trivial fix for a real memory corruption bug ## PHASE 9: FINAL SYNTHESIS **Evidence FOR backporting:** - Fixes real memory corruption (skb_shared_info overwrite in interrupt context) - Only 2 lines added — obviously correct bounds check - Buggy code exists since initial kernel tree — affects ALL stable trees - Patch applies cleanly to all stable trees (verified v5.15, v6.1, v6.6) - Acked by original driver author (Joerg Reuter) - Applied by netdev maintainer (Jakub Kicinski) - No dependencies, fully self-contained - Zero regression risk **Evidence AGAINST backporting:** - Requires CAP_SYS_RAWIO (privileged) to trigger - Niche driver (ham radio hardware) **Stable rules checklist:** 1. Obviously correct and tested? **YES** — trivial 2-line bounds check, acked by driver author 2. Fixes a real bug? **YES** — memory corruption from unchecked userspace input 3. Important issue? **YES** — memory corruption in interrupt context 4. Small and contained? **YES** — 2 lines in one file 5. No new features/APIs? **YES** — pure validation addition 6. Applies to stable? **YES** — verified identical code in all active stable trees ## Verification - [Phase 1] Parsed tags: Acked-by Joerg Reuter (driver author), SOB by Jakub Kicinski (netdev maintainer) - [Phase 2] Diff: 2 lines added to `scc_net_siocdevprivate()`, bounds check on `memcfg.bufsize` - [Phase 3] git blame: buggy code at line 1912 dates to `^1da177e4c3f41` (initial git import, 2005), present in ALL stable trees - [Phase 3] git log v6.1/v6.6/v5.15 -- scc.c: only treewide changes, SIOCSCCSMEM handler untouched - [Phase 5] Traced `scc->stat.bufsize` consumer: `scc_rxint()` line 535 calls `dev_alloc_skb(bufsize)`, line 546 `skb_put_u8` overflows when bufsize=0 - [Phase 6] git show v6.1/v6.6/v5.15: SIOCSCCSMEM handler code is byte- for-byte identical — clean apply confirmed - [Phase 4] Lore unavailable due to anti-scraping protection — could not verify discussion thread directly - [Phase 8] Failure mode: memory corruption (skb_shared_info overwrite) in interrupt context, severity HIGH **YES** drivers/net/hamradio/scc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c index ae5048efde686..8569db4a71401 100644 --- a/drivers/net/hamradio/scc.c +++ b/drivers/net/hamradio/scc.c @@ -1909,6 +1909,8 @@ static int scc_net_siocdevprivate(struct net_device *dev, if (!capable(CAP_SYS_RAWIO)) return -EPERM; if (!arg || copy_from_user(&memcfg, arg, sizeof(memcfg))) return -EINVAL; + if (memcfg.bufsize < 16) + return -EINVAL; scc->stat.bufsize = memcfg.bufsize; return 0; -- 2.53.0