|
client lifecycle (#265)
PR #262 introduced per-instance UX_HOST_CLASS_HID_CLIENT allocation in
client_search.c. However, keyboard/mouse/remote_control activate handlers
already embed a UX_HOST_CLASS_HID_CLIENT inside their own combined
allocation (e.g. UX_HOST_CLASS_HID_CLIENT_KEYBOARD), override
hid->hid_client with the embedded copy, and then free the entire combined
struct (as 'keyboard_instance', the first field) during deactivation.
This created two bugs:
1. Memory leak: the per-instance copy from client_search was abandoned
when activate handlers replaced hid->hid_client with their embedded
copy.
2. Double-free / UX_MEMORY_CORRUPTED: deactivate.c freed hid->hid_client
after calling the handler, but for keyboard/mouse/remote_control the
deactivate handler had already freed the entire combined allocation
(which contains the embedded hid_client), causing a second free of a
pointer into the middle of a now-freed block.
Fix:
- keyboard/mouse/remote_control activate: free the per-instance copy from
client_search before overriding hid->hid_client with the embedded one.
- keyboard/mouse/remote_control deactivate: null hid->hid_client after
freeing the combined struct, signalling that cleanup is done.
- deactivate.c: re-check hid_client != NULL after calling the handler
before freeing; keyboard/mouse/remote_control will have nulled it,
simple clients will not.
- keyboard/mouse ACTIVATE_WAIT error paths (standalone): null
hid->hid_client after freeing the combined struct so that the generic
cleanup in entry.c skips the already-freed pointer.
- entry.c standalone ACTIVATE_WAIT error: guard the free with a NULL
check to safely handle both cases.
Discovered while investigating test failures introduced by PR #262.
All 430 tests pass after this fix.
Co-authored-by: Copilot <[email protected]>
|