Repository navigation
gadget: Use ForkMonitor - #1263
wertyutreethgfd wants to merge 5 commits into
Conversation
Gadget never prepared/recovered GumJS around fork(), so a JS interceptor in a fork-without-exec child deadlocked on the QuickJS mutex and the parent sat in waitpid. Install a thin ForkHandler (no agent controller or child-gating): prepare/recover GLib, GIO, Gum, GumJS and recreate the Gadget worker. Also treat clone/clone3/syscall without CLONE_VM as process creation. vfork is still redirected to fork, same as the agent.
libc clone() and bionic __clone have different ABIs; treating flags as a function pointer skipped process-creating clones. Mark the hooks unignorable, install pthread_atfork as a fallback, and recover in the clone(fn) child trampoline.
Joining the Gadget worker or gum-js-loop in the parent around fork() wedges the host. Child recovery must also require a new pid so a clone on_leave of 0 in the still-live parent does not reinitialize locks. Ignore SYS_vfork; it shares the parent's address space.
Short-lived helpers are not a live session; waiting for the worker leaves _exit stuck on g_cond_wait.
|
Pushed a follow-up so short-lived fork children skip async exit teardown. A helper is not a live Gadget session. |
|
Thanks for wiring this up, much appreciated! One fundamental issue: Could the handler mirror the agent's The Thanks again! 🙏 |
|
Tried mirroring Agent
The helper never reaches So Gadget cannot use the Agent prepare/recover pairing. Empty
|
pause_all copies held pool mutexes; child resume_all then blocks in g_mutex_lock. Empty prepare plus child Gum recover is required.
27f941f to
a29f359
Compare
|
Second leftover, same frames:
Helpers never reach |
oleavr asked for ForkMonitor in Gadget instead of skipping JS in unrecovered children (frida/frida-gum#1165).
Gadget never installed ForkMonitor. Agent already does, which is why this hang shows up on Gadget.
This is a thin ForkHandler: no frida-server, no child-gating, no session rebuild. On fork it pr 8000 epare/recover-s GLib, GIO, Gum, GumJS and recreates the Gadget worker. The old
supports_async_exitcheck existed because that worker dies across an unnoticed fork.Also:
clone/clone3/ libcsyscallwithoutCLONE_VMare treated as process creation (pthread clone withCLONE_VMis ignored)cloneinside libcforkis ignored (alreadyFORKING)vforkis still replaced withfork, same as the agentNeeds the gumjs recover follow-up so a mutex owned by a vanished thread, and fork-from-JS, actually recover instead of just restarting a scheduler that is still pointing at a dead thread.
JS listeners run in the child after recover. A short-lived helper that then calls
Java.performstill needs a live ART; we do not skip JS there.Fixes frida/frida-gum#1163