* [PATCH AUTOSEL 7.0-5.10] net: rose: reject truncated CLEAR_REQUEST frames in state machines
[not found] <20260420132314.1023554-1-sashal@kernel.org>
@ 2026-04-20 13:17 ` Sasha Levin
2026-04-20 13:20 ` [PATCH AUTOSEL 7.0-5.10] net: hamradio: scc: validate bufsize in SIOCSCCSMEM ioctl Sasha Levin
1 sibling, 0 replies; 2+ messages in thread
From: Sasha Levin @ 2026-04-20 13:17 UTC (permalink / raw)
To: patches, stable
Cc: Mashiro Chen, Jakub Kicinski, Sasha Levin, davem, edumazet,
pabeni, linux-hams, netdev, linux-kernel
From: Mashiro Chen <mashiro.chen@mailbox.org>
[ Upstream commit 2835750dd6475a5ddc116be0b4c81fee8ce1a902 ]
All five ROSE state machines (states 1-5) handle ROSE_CLEAR_REQUEST
by reading the cause and diagnostic bytes directly from skb->data[3]
and skb->data[4] without verifying that the frame is long enough:
rose_disconnect(sk, ..., skb->data[3], skb->data[4]);
The entry-point check in rose_route_frame() only enforces
ROSE_MIN_LEN (3 bytes), so a remote peer on a ROSE network can
send a syntactically valid but truncated CLEAR_REQUEST (3 or 4
bytes) while a connection is open in any state. Processing such a
frame causes a one- or two-byte out-of-bounds read past the skb
data, leaking uninitialized heap content as the cause/diagnostic
values returned to user space via getsockopt(ROSE_GETCAUSE).
Add a single length check at the rose_process_rx_frame() dispatch
point, before any state machine is entered, to drop frames that
carry the CLEAR_REQUEST type code but are too short to contain the
required cause and diagnostic fields.
Signed-off-by: Mashiro Chen <mashiro.chen@mailbox.org>
Link: https://patch.msgid.link/20260408172551.281486-1-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:
I now have all the information needed for a complete analysis.
---
## PHASE 1: COMMIT MESSAGE FORENSICS
**Step 1.1: PARSE THE SUBJECT LINE**
- Subsystem: `net: rose:`
- Action verb: "reject" (implies adding a safety check / validation — a
bug fix)
- Summary: Reject truncated CLEAR_REQUEST frames to prevent out-of-
bounds read
Record: [net: rose] [reject] [Add length validation for CLEAR_REQUEST
frames to prevent OOB read]
**Step 1.2: PARSE ALL COMMIT MESSAGE TAGS**
- `Signed-off-by: Mashiro Chen <mashiro.chen@mailbox.org>` — author
- `Link: https://patch.msgid.link/20260408172551.281486-1-
mashiro.chen@mailbox.org` — original patch submission
- `Signed-off-by: Jakub Kicinski <kuba@kernel.org>` — network maintainer
(committed the patch)
- No Fixes: tag (expected for this review pipeline)
- No Reported-by: tag
- No Cc: stable tag
Record: Patch accepted by Jakub Kicinski (net maintainer). Single
standalone patch (not part of a series).
**Step 1.3: ANALYZE THE COMMIT BODY TEXT**
The commit body clearly describes:
- **Bug**: All five ROSE state machines (states 1-5) handle
ROSE_CLEAR_REQUEST by reading `skb->data[3]` and `skb->data[4]`
without verifying the frame is long enough.
- **Root cause**: `rose_route_frame()` only enforces `ROSE_MIN_LEN` (3
bytes), but `data[3]` and `data[4]` need at least 5 bytes.
- **Trigger**: A remote peer on a ROSE network can send a 3- or 4-byte
CLEAR_REQUEST.
- **Consequence**: 1-2 byte out-of-bounds read past skb data, leaking
uninitialized heap content as cause/diagnostic values returned to
userspace via `getsockopt(ROSE_GETCAUSE)`.
Record: OOB read vulnerability. Remote trigger. Info leak to userspace.
Clear mechanism explained.
**Step 1.4: DETECT HIDDEN BUG FIXES**
This is not hidden — it's an explicit security/memory safety bug fix.
The word "reject" means "add missing input validation."
Record: Explicit bug fix, not disguised.
---
## PHASE 2: DIFF ANALYSIS
**Step 2.1: INVENTORY THE CHANGES**
- 1 file changed: `net/rose/rose_in.c`
- +7 lines added (5 lines comment + 2 lines of code)
- Function modified: `rose_process_rx_frame()`
- Scope: Single-file surgical fix
Record: [net/rose/rose_in.c +7/-0] [rose_process_rx_frame] [Single-file
surgical fix]
**Step 2.2: UNDERSTAND THE CODE FLOW CHANGE**
- **Before**: After `rose_decode()` returns the frametype, the code
dispatches directly to state machines. If `frametype ==
ROSE_CLEAR_REQUEST` and `skb->len < 5`, the state machines would read
`skb->data[3]` and `skb->data[4]` beyond the buffer.
- **After**: A length check drops CLEAR_REQUEST frames shorter than 5
bytes before any state machine is entered. This prevents the OOB
access in all 5 state machines with one check.
Record: [Before: no length validation for CLEAR_REQUEST → OOB read |
After: reject truncated frames early]
**Step 2.3: IDENTIFY THE BUG MECHANISM**
Category: **Memory safety fix — out-of-bounds read**
- The frame minimum is 3 bytes (`ROSE_MIN_LEN = 3`)
- `ROSE_CLEAR_REQUEST` needs bytes at offsets 3 and 4 (requiring 5
bytes)
- All five state machines access `skb->data[3]` and `skb->data[4]` when
handling CLEAR_REQUEST
- The OOB-read values are stored in `rose->cause` and
`rose->diagnostic`, which are exposed to userspace via `SIOCRSGCAUSE`
ioctl
Record: [OOB read, 1-2 bytes past skb data] [Remote trigger via
malformed ROSE frame] [Info leak to userspace via ioctl]
**Step 2.4: ASSESS THE FIX QUALITY**
- Obviously correct: The check is trivially verifiable — CLEAR_REQUEST
needs bytes at index 3 and 4, so minimum length must be 5.
- Minimal/surgical: 2 lines of actual code + comment, at a single
dispatch point that covers all 5 state machines.
- Regression risk: Near zero. It only drops malformed frames that would
cause OOB access anyway.
- No side effects: Returns 0 (drops the frame silently), which is the
standard behavior for invalid frames.
Record: [Obviously correct, minimal, near-zero regression risk]
---
## PHASE 3: GIT HISTORY INVESTIGATION
**Step 3.1: BLAME THE CHANGED LINES**
Git blame shows the vulnerable `skb->data[3]` / `skb->data[4]` accesses
originate from commit `1da177e4c3f41` — **Linux 2.6.12-rc2 (April
2005)**. This is the initial import of the Linux kernel into git. The
bug has existed since the very beginning of the ROSE protocol
implementation.
Record: [Buggy code from Linux 2.6.12-rc2 (2005)] [Present in ALL stable
trees]
**Step 3.2: FOLLOW THE FIXES TAG**
No Fixes: tag present (expected). Based on blame, the theoretical Fixes:
target would be `1da177e4c3f41 ("Linux-2.6.12-rc2")`.
Record: [Bug exists since initial kernel git import, affects all stable
trees]
**Step 3.3: CHECK FILE HISTORY FOR RELATED CHANGES**
Recent changes to `rose_in.c` are minimal: `d860d1faa6b2c` (refcount
conversion), `a6f190630d070` (drop reason tracking), `b6459415b384c`
(include fix). None conflict with this fix. The fix applies cleanly with
no dependencies.
Record: [No conflicting changes, standalone fix, no dependencies]
**Step 3.4: CHECK THE AUTHOR**
Mashiro Chen has other ROSE/hamradio-related patches (visible in the
.mbx files in the workspace: `v2_20260409_mashiro_chen_net_hamradio_fix_
missing_input_validation_in_bpqether_and_scc.mbx`). The patch was
accepted by Jakub Kicinski, the network subsystem maintainer.
Record: [Author contributes to amateur radio subsystem, patch accepted
by net maintainer]
**Step 3.5: CHECK FOR DEPENDENT/PREREQUISITE COMMITS**
The fix only uses `frametype`, `ROSE_CLEAR_REQUEST`, and `skb->len` —
all of which have existed since the file's creation. No dependencies.
Record: [No dependencies. Applies standalone to any kernel version.]
---
## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
**Step 4.1-4.2: FIND ORIGINAL PATCH DISCUSSION**
b4 dig could not find the exact match (possibly too recent or the commit
hash `028ef9c96e961` is the Linux 7.0 tag, not the fix commit). However,
the Link tag points to
`patch.msgid.link/20260408172551.281486-1-mashiro.chen@mailbox.org`, and
the patch was signed off by Jakub Kicinski, confirming acceptance by the
net maintainer.
Record: [b4 dig could not match (HEAD is Linux 7.0 tag)] [Patch accepted
by Jakub Kicinski (net maintainer)]
**Step 4.3-4.5**: Lore is behind Anubis protection, preventing direct
fetching. But the commit message is detailed enough to fully understand
the bug.
Record: [Lore inaccessible due to bot protection] [Commit message
provides complete technical detail]
---
## PHASE 5: CODE SEMANTIC ANALYSIS
**Step 5.1: KEY FUNCTIONS**
Modified function: `rose_process_rx_frame()`
**Step 5.2: CALLERS**
`rose_process_rx_frame()` is called from:
1. `rose_route_frame()` in `rose_route.c:944` — the main frame routing
entry point from AX.25
2. `rose_loopback_dequeue()` in `rose_loopback.c:93` — the loopback
queue processor
Both callers only enforce `ROSE_MIN_LEN` (3 bytes) before calling,
confirming the vulnerability.
**Step 5.3: CALLEES**
The state machine functions (`rose_state1_machine` through
`rose_state5_machine`) are callees. All five access `skb->data[3]` and
`skb->data[4]` for CLEAR_REQUEST, making the single check at the
dispatch point the optimal fix location.
**Step 5.4: CALL CHAIN / REACHABILITY**
- `rose_route_frame()` is the AX.25 protocol handler for ROSE
(`rose_pid.func = rose_route_frame`), registered at module load via
`ax25_protocol_register()`. This is directly reachable from network
input — a remote peer on a ROSE network can send malformed frames.
- `rose_loopback_dequeue()` processes locally-queued frames. Also
reachable.
Record: [Remotely triggerable via ROSE network frames. Both entry paths
affected.]
**Step 5.5: USER DATA LEAK PATH**
Verified: `rose_disconnect()` stores the OOB-read values in
`rose->cause` and `rose->diagnostic`. The `SIOCRSGCAUSE` ioctl in
`af_rose.c:1389-1393` copies these to userspace via `copy_to_user()`.
This completes the info leak chain from OOB kernel heap read to
userspace.
Record: [Complete info leak chain verified: OOB read →
rose->cause/diagnostic → ioctl → userspace]
---
## PHASE 6: CROSS-REFERENCING AND STABLE TREE ANALYSIS
**Step 6.1: DOES THE BUGGY CODE EXIST IN STABLE TREES?**
The buggy code dates from Linux 2.6.12-rc2 (2005). Very few changes have
been made to `rose_in.c` across kernel versions. Since v5.15, only 3
unrelated commits touched this file (include changes, pfmemalloc
tracking, refcount conversion). The vulnerable
`skb->data[3]`/`skb->data[4]` accesses are present in ALL active stable
trees.
Record: [Bug present in all stable trees: 5.4.y, 5.10.y, 5.15.y, 6.1.y,
6.6.y, 6.12.y]
**Step 6.2: BACKPORT COMPLICATIONS**
The fix patches the `rose_process_rx_frame()` function which has been
nearly unchanged since 2005. The recent `d860d1faa6b2c` (refcount_t
conversion) doesn't affect the patch point. This will apply cleanly to
all stable trees.
Record: [Clean apply expected for all stable trees]
**Step 6.3: RELATED FIXES IN STABLE**
No related fix for this specific OOB read issue exists in any stable
tree.
Record: [No prior fix for this bug]
---
## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
**Step 7.1: SUBSYSTEM CRITICALITY**
- Subsystem: `net/rose/` — ROSE (Radio Over Serial Ethernet) amateur
radio protocol
- Criticality: PERIPHERAL (niche protocol used by amateur radio
operators)
- However: This is a network protocol reachable from external input,
making it security-relevant despite limited user base.
Record: [net/rose — peripheral subsystem but remotely triggerable,
security-relevant]
**Step 7.2: SUBSYSTEM ACTIVITY**
The ROSE subsystem is mature/stable — minimal development activity. The
file has only had trivial/treewide changes since 2005. This means the
bug has been present for ~21 years.
Record: [Very mature code, minimal activity, bug present for 21 years]
---
## PHASE 8: IMPACT AND RISK ASSESSMENT
**Step 8.1: WHO IS AFFECTED**
Users with `CONFIG_ROSE` enabled who have ROSE sockets open. This is
primarily amateur radio operators using AX.25/ROSE networking.
Record: [Affected: systems with CONFIG_ROSE enabled and active ROSE
connections]
**Step 8.2: TRIGGER CONDITIONS**
- **Remote trigger**: A peer on a ROSE network sends a 3- or 4-byte
frame with frametype byte 0x13 (CLEAR_REQUEST)
- **No authentication needed**: Any ROSE peer can send this
- **Deterministic**: Not a race condition — always triggers on receipt
of truncated frame
- **Any connection state**: All 5 state machines are vulnerable
Record: [Remotely triggerable, no authentication, deterministic, any
connection state]
**Step 8.3: FAILURE MODE SEVERITY**
- **OOB read**: 1-2 bytes read past allocated skb data — reads
uninitialized heap memory
- **Info leak to userspace**: The leaked bytes are stored in
`rose->cause`/`rose->diagnostic` and returned via `SIOCRSGCAUSE` ioctl
- Severity: **HIGH** — kernel heap info leak reachable from network
input
Record: [Severity: HIGH — remotely-triggered kernel heap info leak]
**Step 8.4: RISK-BENEFIT RATIO**
- **Benefit**: Fixes a remotely-triggered OOB read / kernel info leak in
a 21-year-old bug
- **Risk**: 2 lines of code, obviously correct bounds check, zero
regression potential
- **Ratio**: Extremely favorable — maximum benefit, minimum risk
Record: [Benefit: HIGH (security fix) | Risk: VERY LOW (2 lines,
trivially correct) | Ratio: Strongly favorable]
---
## PHASE 9: FINAL SYNTHESIS
**Step 9.1: COMPILE THE EVIDENCE**
Evidence FOR backporting:
- Fixes a remotely-triggerable out-of-bounds read (security
vulnerability)
- Kernel heap info leak to userspace via ioctl (complete exploit chain
verified)
- Bug present since Linux 2.6.12 (2005) — affects ALL stable trees
- Fix is 2 lines of code, obviously correct
- No dependencies, applies cleanly to all stable trees
- Accepted by net maintainer Jakub Kicinski
- Single centralized check covers all 5 vulnerable state machines
Evidence AGAINST backporting:
- ROSE is a niche protocol (limited user base)
- No Fixes: tag (expected)
Unresolved:
- Could not access lore discussion (Anubis protection)
**Step 9.2: STABLE RULES CHECKLIST**
1. Obviously correct and tested? **YES** — trivial bounds check,
accepted by net maintainer
2. Fixes a real bug? **YES** — OOB read with info leak to userspace
3. Important issue? **YES** — security vulnerability (remotely-triggered
kernel info leak)
4. Small and contained? **YES** — 7 lines added (2 code + 5 comment),
single file
5. No new features or APIs? **YES** — only adds validation
6. Can apply to stable trees? **YES** — no conflicting changes, code
unchanged since 2005
**Step 9.3: EXCEPTION CATEGORIES**
Not an exception category — this is a standard security bug fix, which
is core stable material.
**Step 9.4: DECISION**
This is a textbook stable backport candidate: a small, obvious security
fix for a remotely-triggerable OOB read that has been present for 21
years in all kernel versions.
---
## Verification
- [Phase 1] Parsed tags: Signed-off-by Jakub Kicinski (net maintainer),
Link to original patch
- [Phase 2] Diff analysis: +7 lines (2 code + 5 comment) in
rose_process_rx_frame(), adds `skb->len < 5` check for CLEAR_REQUEST
- [Phase 2] Verified all 5 state machines access `skb->data[3]` and
`skb->data[4]` for CLEAR_REQUEST (lines 58, 81, 123, 236, 256 of
rose_in.c)
- [Phase 3] git blame: buggy code from `1da177e4c3f41` (Linux
2.6.12-rc2, April 2005), present in all stable trees
- [Phase 3] git log: only 3 unrelated changes to rose_in.c since v5.15,
fix applies cleanly
- [Phase 4] b4 dig: could not match (HEAD is Linux 7.0 tag, not the fix
commit)
- [Phase 4] UNVERIFIED: Full lore discussion (Anubis protection blocked
access)
- [Phase 5] Verified callers: rose_route_frame() and
rose_loopback_dequeue() both only check ROSE_MIN_LEN (3 bytes)
- [Phase 5] Verified info leak chain: OOB values →
rose->cause/diagnostic → SIOCRSGCAUSE ioctl → copy_to_user
- [Phase 5] Verified ROSE_MIN_LEN = 3 and ROSE_CLEAR_REQUEST = 0x13 in
include/net/rose.h
- [Phase 6] Code exists unchanged in all active stable trees (v5.4+)
- [Phase 7] net/rose is peripheral but network-reachable (security-
relevant)
- [Phase 8] Failure mode: remotely-triggered kernel heap OOB read with
info leak to userspace, severity HIGH
**YES**
net/rose/rose_in.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/net/rose/rose_in.c b/net/rose/rose_in.c
index 0276b393f0e53..e268005819627 100644
--- a/net/rose/rose_in.c
+++ b/net/rose/rose_in.c
@@ -271,6 +271,13 @@ int rose_process_rx_frame(struct sock *sk, struct sk_buff *skb)
frametype = rose_decode(skb, &ns, &nr, &q, &d, &m);
+ /*
+ * ROSE_CLEAR_REQUEST carries cause and diagnostic in bytes 3..4.
+ * Reject a malformed frame that is too short to contain them.
+ */
+ if (frametype == ROSE_CLEAR_REQUEST && skb->len < 5)
+ return 0;
+
switch (rose->state) {
case ROSE_STATE_1:
queued = rose_state1_machine(sk, skb, frametype);
--
2.53.0
^ permalink raw reply related [flat|nested] 2+ messages in thread* [PATCH AUTOSEL 7.0-5.10] net: hamradio: scc: validate bufsize in SIOCSCCSMEM ioctl
[not found] <20260420132314.1023554-1-sashal@kernel.org>
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:20 ` Sasha Levin
1 sibling, 0 replies; 2+ messages in thread
From: Sasha Levin @ 2026-04-20 13:20 UTC (permalink / raw)
To: patches, stable
Cc: Mashiro Chen, Joerg Reuter, Jakub Kicinski, Sasha Levin,
andrew+netdev, davem, edumazet, pabeni, linux-hams, netdev,
linux-kernel
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
^ permalink raw reply related [flat|nested] 2+ messages in thread