Skip to content

Navigation Menu

Sign in
Sign up

hid: ipts: Fix double list_del race in ipts_mei_search() - #178

Open
joshuaspaulding wants to merge 1 commit into
linux-surface:v6.19-surface-devel from
joshuaspaulding:ipts-fix-mei-search-race
Open

hid: ipts: Fix double list_del race in ipts_mei_search() #178
joshuaspaulding wants to merge 1 commit into
linux-surface:v6.19-surface-devel from
joshuaspaulding:ipts-fix-mei-search-race

Conversation

@joshuaspaulding

@joshuaspaulding joshuaspaulding commented Sep 3, 2026
edited
Loading

Copy link
Copy Markdown

Summary

ipts_mei_search() walks the received-message list under the read side of message_lock, drops the lock, then re-takes it for writing to unlink the entry it found. Two waiters for the same command code (typically the receiver poll thread and a userspace hidraw raw request, both inside ipts_control_send_feedback()) can each find the same entry during their read-locked walk and then both unlink and free it. The second list_del() hits LIST_POISON and, with CONFIG_DEBUG_LIST, oopses the poll kthread:

list_del corruption, ...->next is LIST_POISON1 (dead000000000100)
kernel BUG at lib/list_debug.c:56!
RIP: __list_del_entry_valid_or_report.cold
Call Trace:
 ipts_mei_search+0x83/0x150 [ipts]
 ipts_mei_recv+0x61/0x190 [ipts]
 ipts_cmd_recv_timeout+0x2f/0x90 [ipts]
 ipts_control_send_feedback+0x81/0xc0 [ipts]
 ipts_receiver_poll_loop.cold+0x89/0x11c [ipts]
 ipts_thread_runner+0x21/0x40 [ipts]

Without CONFIG_DEBUG_LIST it surfaces as a general protection fault on 0xdead000000000108 in ipts_mei_search(). The other caller is then stuck in D state inside the driver, so every later suspend fails with "tasks refusing to freeze" until reboot.

This is the same trace as linux-surface/linux-surface#2122 and linux-surface/intel-precise-touch#33.

The fix holds the write lock across the search and the unlink, so a message can only be claimed by one caller.

Testing

Surface Pro 7 (IPTS 045E:099F, EDS v2, poll mode). Reproduced on 6.12.107 with the stock patch series: oops on resume from s2idle while iptsd was being restarted, followed by an unfreezable iptsd for the rest of the boot. Rebuilt 6.12.107 with this change and ran repeated s2idle suspend/resume cycles with iptsd stopped before sleep and restarted on wake, which exercises the poll thread and the hidraw path concurrently. No oops, poll thread and iptsd healthy after every cycle.

The drivers/hid/ipts/mei.c in this branch is identical to the 6.12 series version, so the patch applies unchanged across the maintained branches.

ipts_mei_search() looks up a matching response under the read side of
message_lock, drops the lock, and then re-acquires it for writing to
unlink the entry. Two concurrent callers waiting for the same command
code (typically the receiver poll thread and a userspace hidraw raw
request, both inside ipts_control_send_feedback()) can each find the
same entry during their read-locked walk and then both unlink and free
it. The second list_del() hits LIST_POISON and, with CONFIG_DEBUG_LIST,
oopses the poll kthread:
 list_del corruption, ...->next is LIST_POISON1 (dead000000000100)
 kernel BUG at lib/list_debug.c:56!
 RIP: __list_del_entry_valid_or_report.cold
 Call Trace:
 ipts_mei_search+0x83/0x150 [ipts]
 ipts_mei_recv+0x61/0x190 [ipts]
 ipts_cmd_recv_timeout+0x2f/0x90 [ipts]
 ipts_control_send_feedback+0x81/0xc0 [ipts]
 ipts_receiver_poll_loop.cold+0x89/0x11c [ipts]
 ipts_thread_runner+0x21/0x40 [ipts]
Without CONFIG_DEBUG_LIST the same race shows up as a general
protection fault on 0xdead000000000108 in ipts_mei_search(). The other
caller is then left blocked in D state inside the driver, which makes
every later suspend fail with "tasks refusing to freeze". Seen on
resume from s2idle on a Surface Pro 7 while iptsd was (re)started.
Hold the write lock across the search and the unlink so that a message
can only be claimed by one caller.
Signed-off-by: Josh Spaulding <git@spaulding.app>

Copy link
Copy Markdown

I am not very much up to date on the development procedures here so don't trust me blindly but, should this be posted at https://github.com/linux-surface/intel-precise-touch?

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /