hid_error(NULL) hands out an unsynchronized pointer to the global error string #827
Labels
No labels
3rdparty
Android
API
Author does not respond
bsd
bug
build system/CI
ci-virtual-device
CMake
Contributions Welcome
Core
dependencies
device-specific
documentation
don't_merge
duplicate
enhancement
Example
Haiku
hidraw
hotplug
info required
invalid
libusb
macOS
Misc
Not an issue
question
Release
Test
Test GUI
Windows
wontfix
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-libusb/hidapi#827
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
hid_error(NULL)returnslast_global_error_str(the process-global error string) directly, without holding any lock, while another thread canfree()-and-replace it. Any HIDAPI-owned internal thread that writes the global error therefore races an application'shid_error(NULL)read into a use-after-free — and the application has no way to serialize against a thread it does not own.The hotplug work (#822–#825) sidesteps this by making HIDAPI's internal threads never write the global error string (now stated in
hidapi.h), so the hotplug feature itself is safe. But the underlying reader/writer hazard onlast_global_error_stris pre-existing and broader than hotplug: two application threads that concurrently call an error-setting API andhid_error(NULL)already race, and a writer-side lock cannot close it because the reader escapes with a raw internal pointer.A proper fix (likely for v1.0) is either thread-local error state, or a
hid_error(NULL)that copies into a caller-owned / thread-local buffer instead of returning an internal pointer. Filing so it is not lost.Drafted with Claude Code.