Skip to content

hidpp: match answers only against a live reply buffer (#128, #90) - #129

Merged
mescon merged 1 commit into
masterfrom
fix/stale-answer-buffer
Oct 4, 2026
Merged

mescon merged 1 commit into
masterfrom
fix/stale-answer-buffer

Conversation

@mescon

@mescon mescon commented Oct 3, 2026

Copy link
Copy Markdown
Owner

Fixes the kernel panic a G923 Xbox owner finally photographed in AC EVO (#128), the freeze #90 had been chasing for weeks.

What the photo shows: RIP: hidpp_match_answer+0x8 [hid_logitech_dd], "Fatal exception in interrupt". RDX is the live report (direct-map address), RSI is hidpp->send_receive_buf at a vmap-stack address, and CR2 is that address plus one: the read of question->device_index on a stack that no longer exists.

Why: the raw-event path takes a held send_mutex to mean a synchronous sender is waiting, and matches every incoming HID++ report against send_receive_buf, which points at the previous sender's response on that sender's stack. Four senders in this driver hold the mutex with no response buffer of their own (OLED frame worker, OLED handback, rev-light level sender, and the G923 rev-light worker, which sleeps while holding it). A report arriving during their hold was compared against a dead frame; once the owning process had exited and its stack was unmapped, the read faulted in interrupt context and the kernel panicked, with nothing in the journal.

Fix: clear the pointer under the mutex before releasing it, and run the matcher only with a live pointer.

Tests: the module builds clean on 7.2.6 (clang); tests/effect-math and tests/texture-merge pass. Not reproduced on hardware here (no G923 attached); the mechanism is read from the photo and the code.

The raw-event path took a held send_mutex to mean a sync sender was
waiting, and matched incoming HID++ reports against send_receive_buf,
the previous sender's response on that sender's stack. Four senders
here hold the mutex with no response buffer (the OLED frame worker and
handback, the rev-light level sender, the G923 rev-light worker, which
sleeps under it), so during their hold the stale pointer was followed;
once the owning process had exited and its stack was unmapped, the read
faulted in interrupt context and the kernel panicked with nothing in the
journal. Photographed on a G923 Xbox in AC EVO (#128), the freeze #90
chased: RIP hidpp_match_answer+0x8, RSI a vmap-stack address, CR2 that
address plus one (question->device_index).

Clear the pointer under the mutex before releasing it, and gate the
match on a live pointer as well as the mutex.
@mescon mescon mentioned this pull request Oct 3, 2026
3 tasks done
@sonarqubecloud

sonarqubecloud Bot commented Oct 3, 2026

Copy link
Copy Markdown

@mescon
mescon merged commit 19c9132 into master Oct 4, 2026
18 checks passed
@mescon
mescon deleted the fix/stale-answer-buffer branch October 4, 2026 13:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant