fastrpc: fix use-after-free in close_domain_session during session teardown - #365
Open
Jianping (Jianping-Li) wants to merge 1 commit into
Open
fastrpc: fix use-after-free in close_domain_session during session teardown#365Jianping (Jianping-Li) wants to merge 1 commit into
Jianping (Jianping-Li) wants to merge 1 commit into
Conversation
|
qualcomm/fastrpc.triage This pull request has been marked as stale due to 30 days of inactivity. |
…ardown
close_domain_session() iterated over the per-domain handle lists (nql,
rql and ql) using QLIST_NEXTSAFE_FOR_ALL, which caches the next node
(pnn) up front. Inside the loop body the list mutex is dropped to issue
the remote close:
pthread_mutex_unlock(&hlist[domain].lmut);
remote_handle64_close(hi->local);
pthread_mutex_lock(&hlist[domain].lmut);
NEXTSAFE only guarantees that freeing the current node (pn) is safe; it
does not protect the cached next node (pnn) across the unlock window.
While the lock is dropped, the cascaded cleanup inside the remote close
path and the concurrently exiting listener thread can unlink and free
the node pnn points to. On the next iteration pn = pnn dereferences a
dangling pointer, leading to a use-after-free crash:
close_domain_session (fastrpc_apps_user.c:2284)
remote_session_control (req=7, FASTRPC_SESSION_CLOSE)
Program terminated with signal SIGSEGV
pnn = 0xaaa1b7150f3d /* poisoned next pointer */
This only reproduces on targets that support status notifications: the
FASTRPC_SESSION_CLOSE path in the test app is gated by
status_notif_capability, so targets without notification support never
enter close_domain_session and are unaffected.
Replace the NEXTSAFE traversal with a pop-based loop that re-reads the
list head under the lock on every iteration and unlinks the node with
QList_Pop before dropping the mutex. The node is off the list before the
remote close runs, so neither the close cascade nor the listener thread
can free a node we still reference, eliminating the dangling next
pointer. Apply the same fix to all three lists (nql, rql, ql).
Signed-off-by: Jianping Li <jianping.li@oss.qualcomm.com>
Jianping (Jianping-Li)
force-pushed
the
close_session
branch
from
August 31, 2026 02:37
f1a1eca to
76eeb7a
Compare
Ekansh Gupta (ekanshibu)
approved these changes
Sep 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
close_domain_session() iterated over the per-domain handle lists (nql, rql and ql) using QLIST_NEXTSAFE_FOR_ALL, which caches the next node (pnn) up front. Inside the loop body the list mutex is dropped to issue the remote close:
NEXTSAFE only guarantees that freeing the current node (pn) is safe; it does not protect the cached next node (pnn) across the unlock window. While the lock is dropped, the cascaded cleanup inside the remote close path and the concurrently exiting listener thread can unlink and free the node pnn points to. On the next iteration pn = pnn dereferences a dangling pointer, leading to a use-after-free crash:
This only reproduces on targets that support status notifications: the FASTRPC_SESSION_CLOSE path in the test app is gated by status_notif_capability, so targets without notification support never enter close_domain_session and are unaffected.
Replace the NEXTSAFE traversal with a pop-based loop that re-reads the list head under the lock on every iteration and unlinks the node with QList_Pop before dropping the mutex. The node is off the list before the remote close runs, so neither the close cascade nor the listener thread can free a node we still reference, eliminating the dangling next pointer. Apply the same fix to all three lists (nql, rql, ql).