Skip to content

Fix use-after-free in process scheduling lists#2146

Open
petermm wants to merge 1 commit intoatomvm:mainfrom
petermm:fix-waiting_processes
Open

Fix use-after-free in process scheduling lists#2146
petermm wants to merge 1 commit intoatomvm:mainfrom
petermm:fix-waiting_processes

Conversation

@petermm
Copy link
Contributor

@petermm petermm commented Feb 26, 2026

While reviewing #2139 AI found below:

https://ampcode.com/threads/T-019c9441-412f-768c-83d5-9f8982eb753c#message-21-block-0

So AI slop/hallucination danger, but it did call it a "time bomb" when I asked how severe it was - would only happen under memory pressure..

When do_spawn fails after context_new has been called, context_destroy is invoked directly. context_new calls globalcontext_init_process which adds the context to both processes_table and waiting_processes, but context_destroy only removed from processes_table. The freed context's node remained linked in waiting_processes, causing a use-after-free corruption of the scheduling list.

Fix by adding a spinlock-protected list_remove + list_init of processes_list_head in context_destroy. The list_init makes the node self-referential so that a second list_remove (from callers like scheduler_terminate that already do the removal before calling context_destroy) is a safe no-op.

Also remove the now-redundant explicit removal in the native handler kill path of scheduler_run, since context_destroy handles it.

These changes are made under both the "Apache 2.0" and the "GNU Lesser General
Public License 2.1 or later" license terms (dual license).

SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later

When `do_spawn` fails after `context_new` has been called,
`context_destroy` is invoked directly. `context_new` calls
`globalcontext_init_process` which adds the context to both
`processes_table` and `waiting_processes`, but `context_destroy`
only removed from `processes_table`. The freed context's node
remained linked in `waiting_processes`, causing a use-after-free
corruption of the scheduling list.

Fix by adding a spinlock-protected `list_remove` +  `list_init`
of `processes_list_head` in `context_destroy`. The `list_init`
makes the node self-referential so that a second `list_remove`
(from callers like `scheduler_terminate` that already do the
removal before calling `context_destroy`) is a safe no-op.

Also remove the now-redundant explicit removal in the native
handler kill path of `scheduler_run`, since `context_destroy`
handles it.

Signed-off-by: Peter M <petermm@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant