SIGKILL teardown bypasses the hardened exit path
Problem
The SIGKILL branch in kernel/src/syscall/signal.rs::send_signal_to_process eagerly calls process.terminate(-9). That synchronously reaches cleanup_cow_frames() and then frame_decref/deallocate_frame while the victim thread may still be executing at EL0 on another CPU. This is a pre-existing use-after-free class in main's behavior; it was not introduced by the R23 round 3 changes.
The path does not quiesce the victim's scheduler-owned threads: it does not call terminate_process_threads, send a reschedule SGI/IPI, or wait for a thread executing on a peer CPU to leave EL0. After R23 round 3 reverts the unsafe attempted fix, this again exactly matches main's current SIGKILL behavior.
Two related corners need to be handled:
- R23's retained clone fix transfers an aarch64 clone child's kernel-stack allocation to the scheduler-owned thread so retirement grace and liveness checks protect it. If SIGKILL never causes that scheduler thread to reach
Terminated, the kernel stack can remain retained indefinitely after waitpid reaps the process.
- SIGKILL does not generate
SIGCHLD at kill time. The parent learns about the exit only if and when the victim's thread later runs its own teardown pass naturally.
Direction
Route SIGKILL through the hardened teardown path: use terminate_process_threads together with exit_process's unconditional, grace-stamped resource deferral. Expedite that path through the existing SGI_RESCHEDULE mechanism so a victim is forced off any peer CPU promptly instead of relying on its next natural reschedule. PR #418's deferral machinery and the R23 round 3 review findings provide the relevant background.
This issue is scoped to designing and implementing that complete quiescence-and-deferral flow; the R23 round 3 branch intentionally does not implement it.
SIGKILL teardown bypasses the hardened exit path
Problem
The
SIGKILLbranch inkernel/src/syscall/signal.rs::send_signal_to_processeagerly callsprocess.terminate(-9). That synchronously reachescleanup_cow_frames()and thenframe_decref/deallocate_framewhile the victim thread may still be executing at EL0 on another CPU. This is a pre-existing use-after-free class in main's behavior; it was not introduced by the R23 round 3 changes.The path does not quiesce the victim's scheduler-owned threads: it does not call
terminate_process_threads, send a reschedule SGI/IPI, or wait for a thread executing on a peer CPU to leave EL0. After R23 round 3 reverts the unsafe attempted fix, this again exactly matches main's current SIGKILL behavior.Two related corners need to be handled:
Terminated, the kernel stack can remain retained indefinitely afterwaitpidreaps the process.SIGCHLDat kill time. The parent learns about the exit only if and when the victim's thread later runs its own teardown pass naturally.Direction
Route SIGKILL through the hardened teardown path: use
terminate_process_threadstogether withexit_process's unconditional, grace-stamped resource deferral. Expedite that path through the existingSGI_RESCHEDULEmechanism so a victim is forced off any peer CPU promptly instead of relying on its next natural reschedule. PR #418's deferral machinery and the R23 round 3 review findings provide the relevant background.This issue is scoped to designing and implementing that complete quiescence-and-deferral flow; the R23 round 3 branch intentionally does not implement it.