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

Abierto
#1,894 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
3/5
Tiempo estimado
1-2 días
Aptitud para principiantes
57/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
c
Área
backend

Línea de trabajo

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.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

(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.

Lenguaje dominante
C
Estrellas
3.9k
Forks
389
Merge medio
4 d 5 h
PR fusionados (30 d)
16

Preparar el entorno

Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de quickjs-ng/quickjs

Todos los issues de quickjs-ng/quickjs

Issues similares

Más issues de C

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.