From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: "Benoît Sevens" <bsevens@google.com>,
"Silvan Jegen" <s.jegen@gmail.com>,
"Jiri Kosina" <jkosina@suse.com>,
"Sasha Levin" <sashal@kernel.org>,
erazor_de@users.sourceforge.net, jikos@kernel.org,
bentiss@kernel.org, linux-input@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: [PATCH AUTOSEL 6.19-5.10] HID: roccat: fix use-after-free in roccat_report_event
Date: Tue, 14 Apr 2026 07:25:02 -0400 [thread overview]
Message-ID: <20260414112509.410217-6-sashal@kernel.org> (raw)
In-Reply-To: <20260414112509.410217-1-sashal@kernel.org>
From: Benoît Sevens <bsevens@google.com>
[ Upstream commit d802d848308b35220f21a8025352f0c0aba15c12 ]
roccat_report_event() iterates over the device->readers list without
holding the readers_lock. This allows a concurrent roccat_release() to
remove and free a reader while it's still being accessed, leading to a
use-after-free.
Protect the readers list traversal with the readers_lock mutex.
Signed-off-by: Benoît Sevens <bsevens@google.com>
Reviewed-by: Silvan Jegen <s.jegen@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Good. Now I have all the information needed for a complete analysis.
---
## FULL ANALYSIS
### PHASE 1: COMMIT MESSAGE FORENSICS
**Step 1.1: Subject Line**
- Subsystem: `HID: roccat`
- Action verb: "fix"
- Summary: Fix use-after-free in `roccat_report_event` — a clear bug
fix.
- Record: [HID: roccat] [fix] [use-after-free when iterating readers
list without lock]
**Step 1.2: Tags**
- `Signed-off-by: Benoît Sevens <bsevens@google.com>` — Author, Google
security researcher
- `Reviewed-by: Silvan Jegen <s.jegen@gmail.com>` — Review from external
developer
- `Signed-off-by: Jiri Kosina <jkosina@suse.com>` — HID subsystem
maintainer accepted it
- No Fixes: tag, no Cc: stable, no Reported-by — expected for manual
review candidates
- Record: Accepted by HID maintainer Jiri Kosina. Author is a Google
security researcher (bsevens@google.com — Benoît Sevens is known for
kernel security work).
**Step 1.3: Commit Body Analysis**
- Bug: `roccat_report_event()` iterates `device->readers` list without
holding `readers_lock`
- Race: Concurrent `roccat_release()` can remove and free a reader while
it's being accessed
- Failure mode: Use-after-free — accessing freed memory
- Fix: Add `readers_lock` around the list traversal
- Record: Clear UAF bug. The race is between report_event (iterating
readers) and release (freeing a reader). Author explains root cause
clearly.
**Step 1.4: Hidden Bug Fix?**
- No — this is explicitly labeled as a use-after-free fix. Not disguised
at all.
### PHASE 2: DIFF ANALYSIS
**Step 2.1: Inventory**
- Files changed: 1 (`drivers/hid/hid-roccat.c`)
- Lines added: 2 (`mutex_lock(&device->readers_lock)` and
`mutex_unlock(&device->readers_lock)`)
- Lines removed: 0
- Functions modified: `roccat_report_event()`
- Scope: Single-file, single-function, 2-line surgical fix
- Record: Minimal +2 line fix in one function in one file.
**Step 2.2: Code Flow Change**
- BEFORE: `roccat_report_event()` takes only `cbuf_lock`, then iterates
`device->readers` list
- AFTER: `roccat_report_event()` takes `readers_lock` first, then
`cbuf_lock`, iterates `device->readers`, then unlocks both in reverse
order
- The readers list traversal is now protected against concurrent
modification by `roccat_release()`
**Step 2.3: Bug Mechanism**
- Category: Race condition / Use-after-free
- Mechanism: `list_for_each_entry(reader, &device->readers, node)`
iterates the readers list. Concurrently, `roccat_release()` at line
218-221 takes `readers_lock`, calls `list_del(&reader->node)`,
unlocks, then calls `kfree(reader)`. Without `readers_lock` in
`report_event`, the iterator can be traversing a reader node that gets
deleted and freed mid-iteration.
- Record: Classic list-traversal-vs-concurrent-deletion UAF. Fix is
adding the existing designed-for-this-purpose lock.
**Step 2.4: Fix Quality**
- Obviously correct: The lock `readers_lock` was explicitly designed to
"protect modifications of readers list" (comment at line 48). It's
already used in `roccat_open()` (line 169) and `roccat_release()`
(line 218). The fix simply adds it to the one place that was missing.
- Minimal: Just 2 lines.
- Lock ordering: After fix, `readers_lock` -> `cbuf_lock` in
`roccat_report_event()`. In `roccat_read()`, only `cbuf_lock` is taken
(no `readers_lock`). In `roccat_open()` and `roccat_release()`, only
`readers_lock` is taken (no `cbuf_lock`). No conflicting lock ordering
exists — no deadlock risk.
- Record: Fix is obviously correct, minimal, and safe. No regression
risk.
### PHASE 3: GIT HISTORY
**Step 3.1: Blame**
- The buggy code (list traversal without `readers_lock`) at line 270 was
introduced by commit `206f5f2fcb5ff5` (Stefan Achatz, 2010-05-19), the
original roccat module. This code has been present since Linux
v2.6.35.
- The `cbuf_lock` around it was added later by `cacdb14b1c8d3` (Hyunwoo
Kim, 2022-09-04) for v6.1.
- Record: Buggy code from 2010, present in ALL stable trees. The
readers_lock was always available but never used here.
**Step 3.2: Fixes Tag**
- No Fixes: tag present. Based on blame, the bug was introduced by
`206f5f2fcb5ff5` (v2.6.35, 2010).
**Step 3.3: File History**
- Recent changes to hid-roccat.c are mostly cosmetic (constify,
sysfs_emit, etc.)
- The most relevant prior fix is `cacdb14b1c8d3` ("HID: roccat: Fix use-
after-free in roccat_read()") which added `cbuf_lock` to
`roccat_report_event()`. This fixed a different UAF (concurrent
read/write of cbuf), but did NOT address the readers list race.
- This commit is standalone — no dependencies on other patches.
**Step 3.4: Author**
- Benoît Sevens (bsevens@google.com) has 2 other commits visible in the
tree, both security fixes:
- `3d78386b14445` "HID: wacom: fix out-of-bounds read in
wacom_intuos_bt_irq"
- `b909df18ce2a9` "ALSA: usb-audio: Fix potential out-of-bound
accesses for Extigy and Mbox devices"
- Pattern: Google security researcher finding and fixing kernel
vulnerabilities.
**Step 3.5: Dependencies**
- The fix depends on `cbuf_lock` existing in the function (added by
`cacdb14b1c8d3`, v6.1). For trees v6.1+, this applies cleanly.
- For trees older than v6.1 (5.15, 5.10), the cbuf_lock won't exist, so
the fix would need minor adaptation (just add readers_lock without the
cbuf_lock context). But the readers list traversal and the
readers_lock mutex exist in all trees.
### PHASE 4: MAILING LIST RESEARCH
**Step 4.1-4.4:** Lore searches were blocked by Anubis CAPTCHA. Could
not access mailing list discussions. Record: UNVERIFIED — could not
access lore.kernel.org.
### PHASE 5: CODE SEMANTIC ANALYSIS
**Step 5.1: Functions Modified**
- Only `roccat_report_event()` is modified.
**Step 5.2: Callers**
- `roccat_report_event()` is an EXPORT_SYMBOL_GPL function called from
**16 sites** across 10 different roccat HID drivers (arvo, isku, kone,
koneplus, konepure, kovaplus, pyra, ryos, savu). It's called from
their `raw_event` handlers — the main HID event processing path for
these devices.
**Step 5.3-5.4: Call Chain**
- HID subsystem -> raw_event callback in roccat driver ->
`roccat_report_event()`
- This is the core event reporting path for all Roccat hardware. Any
user with a Roccat device who opens the chardev and then
disconnects/closes while events arrive could trigger the race.
**Step 5.5: Similar Patterns**
- The prior fix `cacdb14b1c8d3` fixed an analogous UAF in this same
function (cbuf access without lock). The readers_lock omission is the
same class of bug — incomplete locking.
### PHASE 6: STABLE TREE ANALYSIS
**Step 6.1: Buggy Code in Stable**
- The original code is from v2.6.35 (2010). Present in ALL active stable
trees.
- The `cbuf_lock` context from `cacdb14b1c8d3` exists in v6.1+. For
v6.1, v6.6, and v6.12+ stable trees, the patch applies cleanly.
- For v5.15 and v5.10 (if still active), minor adaptation needed.
**Step 6.2: Backport Complications**
- For v6.1+: Clean apply expected — the cbuf_lock lines exist as
context.
- For older trees: Trivial adaptation (readers_lock wrapping only the
list traversal).
**Step 6.3: Related Fixes Already in Stable**
- `cacdb14b1c8d3` (cbuf_lock fix) is in v6.1+ stable trees. This new
commit fixes a DIFFERENT, remaining race in the same function.
### PHASE 7: SUBSYSTEM CONTEXT
**Step 7.1:** HID subsystem, `drivers/hid/` — IMPORTANT level. Roccat
devices are popular gaming peripherals.
**Step 7.2:** The hid-roccat.c core hasn't changed much since 2022; it's
mature code with long-standing bugs.
### PHASE 8: IMPACT AND RISK ASSESSMENT
**Step 8.1: Affected Users**
- Users of Roccat gaming hardware (keyboards, mice) using the roccat
chardev for special events. This is a hardware-specific driver but
Roccat is a well-known peripherals brand.
**Step 8.2: Trigger Conditions**
- Race between: event delivery (`roccat_report_event` from HID event
handler) and file close (`roccat_release` from userspace close()).
Triggering requires concurrent device events and chardev fd close.
- An unprivileged user who has access to the device can trigger this
(open/close the chardev while the device is sending events).
- Security relevance: UAF can potentially be exploited for privilege
escalation.
**Step 8.3: Failure Mode Severity**
- Use-after-free: Accessing freed `roccat_reader` memory during list
traversal.
- Consequences: kernel crash/oops, potential memory corruption,
potential security exploit.
- Severity: **HIGH** (UAF = crash or security vulnerability)
**Step 8.4: Risk-Benefit Ratio**
- BENEFIT: High — prevents UAF that can crash the kernel or be
exploited.
- RISK: Very low — 2-line addition of a mutex that was designed for
exactly this purpose, consistent lock ordering, no deadlock risk.
- Ratio: Strongly favorable for backporting.
### PHASE 9: FINAL SYNTHESIS
**Step 9.1: Evidence Summary**
FOR backporting:
- Fixes a real use-after-free bug (HIGH severity)
- 2-line surgical fix — minimal scope
- Obviously correct — uses the existing `readers_lock` for its intended
purpose
- No regression risk — consistent lock ordering verified
- Author is a Google security researcher (credibility)
- Reviewed-by present, accepted by HID maintainer
- Bug present since 2010 — affects all stable trees
- Called from 16 sites across 10 roccat drivers — affects all Roccat
hardware users
AGAINST backporting:
- No Fixes: tag (expected — that's why it needs review)
- Could not verify lore discussion (Anubis blocked)
- Minor: comment says "called from interrupt handler" but function
already uses mutexes (pre-existing, not introduced by this fix)
UNRESOLVED:
- Lore discussion not accessible
**Step 9.2: Stable Rules Checklist**
1. Obviously correct and tested? **YES** — uses existing lock for its
documented purpose
2. Fixes a real bug? **YES** — use-after-free in readers list traversal
3. Important issue? **YES** — UAF = crash or security vulnerability
4. Small and contained? **YES** — 2 lines in one function in one file
5. No new features or APIs? **YES** — purely adding missing locking
6. Can apply to stable trees? **YES** — clean for v6.1+, trivial
adaptation for older
**Step 9.3: Exception Categories**
- Not an exception category — this is a standard bug fix (the best kind
of stable material).
**Step 9.4: Decision**
This is a textbook stable backport candidate: a small, obviously correct
fix for a use-after-free vulnerability found by a security researcher,
with minimal regression risk.
### Verification
- [Phase 1] Parsed tags: Signed-off-by from author (Google security),
Reviewed-by present, maintainer SOB (Jiri Kosina)
- [Phase 2] Diff analysis: +2 lines adding mutex_lock/unlock of
readers_lock around list traversal in roccat_report_event()
- [Phase 2] Lock ordering verified: readers_lock (outer) -> cbuf_lock
(inner) is consistent; roccat_read() takes only cbuf_lock;
roccat_open()/release() take only readers_lock (under devices_lock).
No deadlock path.
- [Phase 3] git blame: buggy code from commit 206f5f2fcb5ff5 (Stefan
Achatz, 2010, v2.6.35), present in all stable trees
- [Phase 3] Prior fix cacdb14b1c8d3 ("Fix use-after-free in
roccat_read()") added cbuf_lock but NOT readers_lock — this is a
different remaining bug
- [Phase 3] Author Benoît Sevens has 2 other security fix commits in the
tree (wacom OOB read, ALSA OOB access)
- [Phase 5] roccat_report_event() called from 16 sites across 10 roccat
drivers — core event path for all Roccat hardware
- [Phase 5] Race confirmed: roccat_release() does list_del+kfree under
readers_lock; roccat_report_event() iterates without lock
- [Phase 6] Buggy code exists in all active stable trees (original from
2010)
- [Phase 6] Clean apply expected for v6.1+ (cbuf_lock context present)
- [Phase 8] Failure mode: UAF -> kernel crash or potential security
exploit, severity HIGH
- UNVERIFIED: Could not access lore.kernel.org discussion due to Anubis
CAPTCHA
**YES**
drivers/hid/hid-roccat.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/hid/hid-roccat.c b/drivers/hid/hid-roccat.c
index c7f7562e22e56..e413662f75082 100644
--- a/drivers/hid/hid-roccat.c
+++ b/drivers/hid/hid-roccat.c
@@ -257,6 +257,7 @@ int roccat_report_event(int minor, u8 const *data)
if (!new_value)
return -ENOMEM;
+ mutex_lock(&device->readers_lock);
mutex_lock(&device->cbuf_lock);
report = &device->cbuf[device->cbuf_end];
@@ -279,6 +280,7 @@ int roccat_report_event(int minor, u8 const *data)
}
mutex_unlock(&device->cbuf_lock);
+ mutex_unlock(&device->readers_lock);
wake_up_interruptible(&device->wait);
return 0;
--
2.53.0
next prev parent reply other threads:[~2026-04-14 11:25 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-14 11:24 [PATCH AUTOSEL 6.19-5.15] pinctrl: intel: Fix the revision for new features (1kOhm PD, HW debouncer) Sasha Levin
2026-04-14 11:24 ` [PATCH AUTOSEL 6.19-6.18] x86: shadow stacks: proper error handling for mmap lock Sasha Levin
2026-04-14 11:24 ` [PATCH AUTOSEL 6.19-6.12] net: sfp: add quirks for Hisense and HSGQ GPON ONT SFP modules Sasha Levin
2026-04-14 11:25 ` [PATCH AUTOSEL 6.19-5.10] wifi: brcmfmac: validate bsscfg indices in IF events Sasha Levin
2026-04-14 11:25 ` [PATCH AUTOSEL 6.19-6.6] platform/x86/amd: pmc: Add Thinkpad L14 Gen3 to quirk_s2idle_bug Sasha Levin
2026-04-14 11:25 ` Sasha Levin [this message]
2026-04-14 11:25 ` [PATCH AUTOSEL 6.19-5.10] ata: ahci: force 32-bit DMA for JMicron JMB582/JMB585 Sasha Levin
2026-04-14 11:25 ` [PATCH AUTOSEL 6.19-6.1] ALSA: hda/realtek: Add quirk for Lenovo Yoga Pro 7 14IAH10 Sasha Levin
2026-04-14 11:25 ` [PATCH AUTOSEL 6.19-5.10] ASoC: stm32_sai: fix incorrect BCLK polarity for DSP_A/B, LEFT_J Sasha Levin
2026-04-14 11:25 ` [PATCH AUTOSEL 6.19-6.18] HID: Intel-thc-hid: Intel-quickspi: Add NVL Device IDs Sasha Levin
2026-04-14 11:25 ` [PATCH AUTOSEL 6.19-5.10] HID: quirks: add HID_QUIRK_ALWAYS_POLL for 8BitDo Pro 3 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=20260414112509.410217-6-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=bentiss@kernel.org \
--cc=bsevens@google.com \
--cc=erazor_de@users.sourceforge.net \
--cc=jikos@kernel.org \
--cc=jkosina@suse.com \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=patches@lists.linux.dev \
--cc=s.jegen@gmail.com \
--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