JS_GetTypedArrayBuffer / JS_GetUint8Array report a stale length for length-tracking views after ArrayBuffer.prototype.resize()

Aperta
#1,894 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
3/5
Tempo stimato
1-2 giorni
Idoneità per principianti
57/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
c
Ambito
backend

Direzione di ricerca

Start in quickjs.c at JS_GetTypedArrayBuffer and JS_GetUint8Array, then compare their length handling with js_typed_array_get_byteLength() and js_array_buffer_update_typed_arrays(). Reproduce with the proposed api-test.c case: resize a buffer after creating length-tracking views and check the reported lengths. Done when both APIs report the views' current lengths after resizing, including the offset Uint16Array case.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

(found when fuzzing quickjab; agentic)


Version: quickjs-ng master at e22ce4d; also v0.16.2.

Summary: for a length-tracking typed array, new Uint8Array(rab) over a resizable ArrayBuffer, both C API calls keep returning the length from when the view was created after the buffer is shrunk. Script code sees the correct byteLength. An embedder that trusts the API reads or writes past the end of the shrunk buffer; in our embedder this showed up as an ASan heap-buffer-overflow.

Repro: a test for api-test.c.
static void typed_array_track_rab_length(void)
{
JSValue u8, u16, ret;
size_t off, len, bpe;
uint8_t *p;

JSRuntime *rt = new_runtime();
JSContext *ctx = JS_NewContext(rt);
ret = eval(ctx, "ab = new ArrayBuffer(64, {maxByteLength: 1 << 20});"
                "u8 = new Uint8Array(ab); u16 = new Uint16Array(ab, 2);"
                "ab.resize(7)");
assert(!JS_IsException(ret));
JS_FreeValue(ctx, ret);
u8 = eval(ctx, "u8");
u16 = eval(ctx, "u16");

ret = JS_GetTypedArrayBuffer(ctx, u8, &off, &len, &bpe);
assert(!JS_IsException
JS_FreeValue(ctx, ret)
assert(off == 0 && len == 7 && bpe == 1);   /* fails: len == 64 */
p = JS_GetUint8Array(c
assert(p);
assert(len == 7);     s: len == 64 */

ret = JS_GetTypedArray&bpe);
assert(!JS_IsException
JS_FreeValue(ctx, ret)
assert(off == 2 && lens: len == 62 */

JS_FreeValue(ctx, u8);
JS_FreeValue(ctx, u16)
JS_FreeContext(ctx);
JS_FreeRuntime(rt);

}

Cause:

  • Both functions return ta->length, the byte length when the view was created.
  • On resize, js_array_buffer_update_typed_arrays() refreshes ta->length only for
    DataView. For typed arrat and leaves ta->lengthalone.
  • js_typed_array_get_byteLength() gets it right: for track_rab it uses count << size_log2.

Proposed fix:
--- a/quickjs.c (JS_GetTypedArrayBuffer)

  • if (pbyte_length)
  •    *pbyte_length = t
    
  • if (pbyte_length)
  •    *pbyte_length = (size_t)p->u.array.count <<
    

typed_array_size_log2(p->c
--- a/quickjs.c (JS_GetUint8Array)

  • *psize = ta->length;
  • *psize = p->u.array.c
  • Fixed-length views are unchanged: once typed_array_is_oob() is false, count == ta->length >> size_log2.
  • Tested: with the fix, apn+UBSan, and run-test262 -c tests.conf reports 0 errors.

Possibly related: the inteo reads ta->length; it mayneed the same treatment.

Found by: fuzzing an embedder (quickjab) with libFuzzer + ASan.

Lingua principale
C
Stelle
3.9k
Fork
389
Merge medio
4g 5h
PR unite (30g)
16

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

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di quickjs-ng/quickjs

Tutte le issue di quickjs-ng/quickjs

Issue simili

Altre issue su C

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.