Skip to content

Conversation

@nickva
Copy link
Contributor

@nickva nickva commented Nov 20, 2025

In #462 during exit we call js_std_free_handlers() then JS_FreeRuntime().

js_std_free_handlers() frees the JSThreadState memory. However, later in JS_FreeRuntime() we run GC, which runs js_worker_finalizer and that accesses the port list from the already freed JSThreadState, so it results in a use-after-free error.

To fix it try to run GC in js_std_free_handlers() just before before cleaning and freeing JSThreadState.

Fix #462

In bellard#462 during exit we call `js_std_free_handlers()` then `JS_FreeRuntime()`.

`js_std_free_handlers()` frees the `JSThreadState` memory. However, later in
`JS_FreeRuntime()` we run GC, which runs `js_worker_finalizer` and that
accesses the port list from the already freed `JSThreadState`, so it results in
a use-after-free error.

To fix it try to run GC in `js_std_free_handlers()` just before before cleaning and
freeing `JSThreadState`.

Fix bellard#462
@nickva
Copy link
Contributor Author

nickva commented Nov 20, 2025

Not sure if this entirely right, maybe it's better if the port list has a mutex and a reference count like message pipes...

It does trigger the UAF from #463 any longer at least:

% make CONFIG_ASAN=n qjs && ./qjs --std ./uaf.js
make: `qjs' is up to date.
qjs(74987,0x7ff85a0d5400) malloc: nano zone abandoned due to inability to reserve vm space.
ReferenceError: 'gc' is not defined
    at set (./uaf.js:9:7)
    at <anonymous> (./uaf.js:14:4)
    at <anonymous> (./uaf.js:15:3)
ReferenceError: could not load module filename 'non-exist.js'

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.

Use-After-Free in list_del

1 participant