Crash in js_map_finalizer when a WeakMap value is the symbol key of the next entry
I maintainer di solito rispondono entro 2 giorni
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 72/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- c, javascript
Direzione di ricerca
The crash is traced to js_map_finalizer and reset_weak_ref in quickjs.c; start by reading those functions and the related weak reference handling around delete_map_weak_ref. Run the supplied WeakMap repro in an asserts-enabled build and an ASAN build. Done when freeing the map no longer crashes or reports a use-after-free, and both repro programs exit normally.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Summary
QuickJS-ng crashes when a WeakMap is freed and the value of one entry is a symbol that is also the key of the next entry. The crash happens in js_map_finalizer: the process dies with SIGSEGV, and an ASAN build reports a heap-use-after-free there. A program that only fills a WeakMap should not crash the runtime.
Environment
- QuickJS-ng 0.17.0, Homebrew build, macOS arm64 (the runs and the crash report below).
- master at 876442b, built by hand with
cc, not with the cmake files: one plain build with asserts enabled, and one ASAN build.
Steps to reproduce
- Save this program as
repro.js:
const m = new WeakMap();
const a = Symbol('a'), b = Symbol('b');
m.set(a, b);
m.set(b, a);
print('done');
- Run
qjs repro.js. - Look at the output and at how the process ends.
Expected result
The program prints done and exits normally.
Actual result
The program prints done, then the process dies with SIGSEGV. The macOS crash report has EXC_BAD_ACCESS at 0x0 in delete_map_weak_ref, called from js_map_finalizer.
Additional observations
- One symbol is enough, and the exit path is not needed. This program crashes at the marked line:
var o = {};
function f() {
var m = new WeakMap(), b = Symbol('b');
m.set(o, b);
m.set(b, 1);
b = undefined;
m = undefined; // crashes here
}
f();
- Objects instead of symbols do not crash.
- With two symbols inside a function, it does not crash either if an unrelated entry is inserted between the two
setcalls, or if the map is freed while the symbols are still referenced. - Both programs also fail on master (876442b). The plain build with asserts enabled stops with:
Assertion failed: (wr != NULL), function delete_map_weak_ref, file quickjs.c, line 53553
- The ASAN build reports heap-use-after-free: a read in
js_map_finalizer(quickjs.c:53886) of memory freed byJS_FreeAtomStruct(quickjs.c:3682), called fromjs_map_finalizer(quickjs.c:53889).
Possible cause
My reading of quickjs.c (line numbers at 876442b):
js_map_finalizer(lines 53870-53895) walks the records withlist_for_each_safe, which saves the next element before it handles the current one.- For each record it frees
mr->value. Objects are deferred, but a symbol is freed at once:JS_FreeAtomStructcallsreset_weak_ref(lines 63369-63454), which unlinks and frees the record keyed by that symbol. - If that record is the saved next element, the loop goes on with a freed record.
Same family as #1352.
- Lingua principale
- C
- Stelle
- 3.9k
- Fork
- 389
- Merge medio
- 4g 1h
- PR unite (30g)
- 24
Preparare l'ambiente
Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di quickjs-ng/quickjs
-
Memory leak in JS_ReadBigInt when a bjson payload is truncated inside a BigIntForse già presa @theaddonn l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
quickjs-ng/quickjs#1836 ·
I maintainer di solito rispondono entro 2 giorni
-
Array.prototype.find frees an element twice when interrupted between iterationsForse già presa @josefguenther l’ha presa 17 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 73/100
quickjs-ng/quickjs#1792 · 1 commento ·
I maintainer di solito rispondono entro 2 giorni
-
Object.prototype.propertyIsEnumerable converts `this` before the property keyForse già presa @SomSamantray l’ha presa 12 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
quickjs-ng/quickjs#1772 ·
I maintainer di solito rispondono entro 2 giorni
-
Deserialization corrupts data or returns `undefined` when a RegExp precedes a shared object referenceForse già presa @Sree24-ui l’ha presa 16 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
quickjs-ng/quickjs#1771 · 2 commenti ·
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 45/100
quickjs-ng/quickjs#1833 ·
I maintainer di solito rispondono entro 2 giorni
Tutte le issue di quickjs-ng/quickjs
Issue simili
-
[mimalloc] update to 3.6.0Apertacategory:port-update
Difficoltà 2/5 1-3 ore Idoneità per principianti 66/100
I maintainer di solito rispondono entro 2 giorni
-
emerge failure MARK mark-unstable media-kit
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
macaroni-os/mark-issues#834 ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
NVIDIA/open-gpu-kernel-modules#1479 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 93/100
webarkit/WebARKitLib#107 ·
I maintainer di solito rispondono entro 1 giorno