public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: Mashiro Chen <mashiro.chen@mailbox.org>,
	Joerg Reuter <jreuter@yaina.de>, Jakub Kicinski <kuba@kernel.org>,
	Sasha Levin <sashal@kernel.org>,
	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	[thread overview]
Message-ID: <20260420132314.1023554-240-sashal@kernel.org> (raw)
In-Reply-To: <20260420132314.1023554-1-sashal@kernel.org>

From: Mashiro Chen <mashiro.chen@mailbox.org>

[ 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 <mashiro.chen@mailbox.org>
Acked-by: Joerg Reuter <jreuter@yaina.de>
Link: https://patch.msgid.link/20260409024927.24397-3-mashiro.chen@mailbox.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

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 <jreuter@yaina.de>` — 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


  parent reply	other threads:[~2026-04-20 13:31 UTC|newest]

Thread overview: 62+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20260420132314.1023554-1-sashal@kernel.org>
2026-04-20 13:16 ` [PATCH AUTOSEL 7.0-5.10] FDDI: defxx: Rate-limit memory allocation errors Sasha Levin
2026-04-20 13:16 ` [PATCH AUTOSEL 6.18] xsk: fix XDP_UMEM_SG_FLAG issues Sasha Levin
2026-04-20 13:17 ` [PATCH AUTOSEL 7.0-5.10] net: rose: reject truncated CLEAR_REQUEST frames in state machines Sasha Levin
2026-04-20 13:17 ` [PATCH AUTOSEL 6.18] netfilter: nfnetlink_queue: nfqnl_instance GFP_ATOMIC -> GFP_KERNEL_ACCOUNT allocation Sasha Levin
2026-04-20 13:17 ` [PATCH AUTOSEL 7.0-6.18] net: mana: hardening: Validate adapter_mtu from MANA_QUERY_DEV_CONFIG Sasha Levin
2026-04-20 13:17 ` [PATCH AUTOSEL 7.0-5.10] enic: add V2 SR-IOV VF device ID Sasha Levin
2026-04-20 13:17 ` [PATCH AUTOSEL 7.0-6.6] ipv6: move IFA_F_PERMANENT percpu allocation in process scope Sasha Levin
2026-04-20 13:17 ` [PATCH AUTOSEL 6.18] netfilter: nfnetlink_log: initialize nfgenmsg in NLMSG_DONE terminator Sasha Levin
2026-04-20 13:17 ` [PATCH AUTOSEL 6.18] net: increase IP_TUNNEL_RECURSION_LIMIT to 5 Sasha Levin
2026-04-20 13:17 ` [PATCH AUTOSEL 7.0-6.1] net: lan743x: fix SGMII detection on PCI1xxxx B0+ during warm reset Sasha Levin
2026-04-20 13:17 ` [PATCH AUTOSEL 7.0-5.10] vmxnet3: Suppress page allocation warning for massive Rx Data ring Sasha Levin
2026-04-20 13:17 ` [PATCH AUTOSEL 6.18] xfrm: Wait for RCU readers during policy netns exit Sasha Levin
2026-04-20 13:18 ` [PATCH AUTOSEL 6.18] ixgbe: stop re-reading flash on every get_drvinfo for e610 Sasha Levin
2026-04-20 13:18 ` [PATCH AUTOSEL 6.18] devlink: Fix incorrect skb socket family dumping Sasha Levin
2026-04-20 13:18 ` [PATCH AUTOSEL 7.0-6.12] net: sfp: add quirk for ZOERAX SFP-2.5G-T Sasha Levin
2026-04-20 13:18 ` [PATCH AUTOSEL 7.0-6.18] ipv6: discard fragment queue earlier if there is malformed datagram Sasha Levin
2026-04-20 13:18 ` [PATCH AUTOSEL 6.18] af_unix: read UNIX_DIAG_VFS data under unix_state_lock Sasha Levin
2026-04-20 13:18 ` [PATCH AUTOSEL 6.18] ipv4: nexthop: allocate skb dynamically in rtm_get_nexthop() Sasha Levin
2026-04-20 13:18 ` [PATCH AUTOSEL 6.18] xfrm: fix refcount leak in xfrm_migrate_policy_find Sasha Levin
2026-04-20 13:18 ` [PATCH AUTOSEL 6.18] selftests: net: bridge_vlan_mcast: wait for h1 before querier check Sasha Levin
2026-04-20 13:18 ` [PATCH AUTOSEL 6.18] xsk: tighten UMEM headroom validation to account for tailroom and min frame Sasha Levin
2026-04-20 13:18 ` [PATCH AUTOSEL 7.0-5.15] gve: fix SW coalescing when hw-GRO is used Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 6.18] netfilter: ip6t_eui64: reject invalid MAC header for all packets Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 6.18] l2tp: Drop large packets with UDP encap Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 7.0-5.10] net: ethernet: ravb: Disable interrupts when closing device Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 7.0] dsa: tag_mxl862xx: set dsa_default_offload_fwd_mark() Sasha Levin
2026-04-20 13:34   ` Daniel Golle
2026-04-20 13:19 ` [PATCH AUTOSEL 7.0-6.1] ipv4: validate IPV4_DEVCONF attributes properly Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 6.18] ipv4: nexthop: avoid duplicate NHA_HW_STATS_ENABLE on nexthop group dump Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 6.18] net: ipa: fix event ring index not programmed for IPA v5.0+ Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 7.0-5.10] net: core: allow netdev_upper_get_next_dev_rcu from bh context Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 6.18] net: txgbe: leave space for null terminators on property_entry Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 7.0-5.10] net: initialize sk_rx_queue_mapping in sk_clone() Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 7.0-6.19] gve: Advertise NETIF_F_GRO_HW instead of NETIF_F_LRO Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 6.18] netfilter: conntrack: add missing netlink policy validations Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 6.18] rtnetlink: add missing netlink_ns_capable() check for peer netns Sasha Levin
2026-04-20 13:19 ` [PATCH AUTOSEL 6.18] ipv6: ioam: fix potential NULL dereferences in __ioam6_fill_trace_data() Sasha Levin
2026-04-20 13:20 ` [PATCH AUTOSEL 7.0-6.1] net: sched: cls_u32: Avoid memcpy() false-positive warning in u32_init_knode() Sasha Levin
2026-04-20 13:20 ` [PATCH AUTOSEL 6.18] xsk: respect tailroom for ZC setups Sasha Levin
2026-04-20 13:20 ` [PATCH AUTOSEL 7.0-6.18] tcp: use WRITE_ONCE() for tsoffset in tcp_v6_connect() Sasha Levin
2026-04-20 13:20 ` [PATCH AUTOSEL 6.18] net: mdio: realtek-rtl9300: use scoped device_for_each_child_node loop Sasha Levin
2026-04-20 13:20 ` [PATCH AUTOSEL 7.0-6.12] net: ethernet: mtk_eth_soc: avoid writing to ESW registers on MT7628 Sasha Levin
2026-04-20 13:20 ` [PATCH AUTOSEL 6.18] ipvs: fix NULL deref in ip_vs_add_service error path Sasha Levin
2026-04-20 13:20 ` [PATCH AUTOSEL 7.0-6.18] net: hsr: emit notification for PRP slave2 changed hw addr on port deletion Sasha Levin
2026-04-20 13:20 ` Sasha Levin [this message]
2026-04-20 13:20 ` [PATCH AUTOSEL 6.18] xfrm: account XFRMA_IF_ID in aevent size calculation Sasha Levin
2026-04-20 13:20 ` [PATCH AUTOSEL 6.18] netfilter: nft_set_pipapo_avx2: don't return non-matching entry on expiry Sasha Levin
2026-04-20 13:20 ` [PATCH AUTOSEL 6.18] bridge: guard local VLAN-0 FDB helpers against NULL vlan group Sasha Levin
2026-04-20 13:21 ` [PATCH AUTOSEL 7.0-5.10] net: hamradio: bpqether: validate frame length in bpq_rcv() Sasha Levin
2026-04-20 13:21 ` [PATCH AUTOSEL 6.18] netfilter: ctnetlink: ensure safe access to master conntrack Sasha Levin
2026-04-20 13:21 ` [PATCH AUTOSEL 7.0-6.18] hinic3: Add msg_send_lock for message sending concurrecy Sasha Levin
2026-04-20 13:21 ` [PATCH AUTOSEL 7.0] netfilter: require Ethernet MAC header before using eth_hdr() Sasha Levin
2026-04-20 13:21 ` [PATCH AUTOSEL 6.18] net: sched: act_csum: validate nested VLAN headers Sasha Levin
2026-04-20 13:21 ` [PATCH AUTOSEL 6.18] net: ipa: fix GENERIC_CMD register field masks for IPA v5.0+ Sasha Levin
2026-04-20 13:21 ` [PATCH AUTOSEL 6.18] dt-bindings: net: Fix Tegra234 MGBE PTP clock Sasha Levin
2026-04-20 13:21 ` [PATCH AUTOSEL 6.18] net: ioam6: fix OOB and missing lock Sasha Levin
2026-04-20 13:21 ` [PATCH AUTOSEL 6.18] ipv4: icmp: fix null-ptr-deref in icmp_build_probe() Sasha Levin
2026-04-20 13:21 ` [PATCH AUTOSEL 6.18] nfc: s3fwrn5: allocate rx skb before consuming bytes Sasha Levin
2026-04-20 13:21 ` [PATCH AUTOSEL 6.18] xsk: validate MTU against usable frame size on bind Sasha Levin
2026-04-20 13:21 ` [PATCH AUTOSEL 6.18] xfrm_user: fix info leak in build_mapping() Sasha Levin
2026-04-20 13:22 ` [PATCH AUTOSEL 6.18] net: lapbether: handle NETDEV_PRE_TYPE_CHANGE Sasha Levin
2026-04-20 13:22 ` [PATCH AUTOSEL 6.18] net: airoha: Fix memory leak in airoha_qdma_rx_process() Sasha Levin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260420132314.1023554-240-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=andrew+netdev@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=jreuter@yaina.de \
    --cc=kuba@kernel.org \
    --cc=linux-hams@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mashiro.chen@mailbox.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=patches@lists.linux.dev \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox