mirror of
https://github.com/bellard/quickjs.git
synced 2026-03-31 12:18:01 +00:00
Fix heap buffer overflow via side-effects in js_typed_array_constructor
Fixes: https://github.com/quickjs-ng/quickjs/issues/1296 Fixes: https://github.com/bellard/quickjs/issues/478
This commit is contained in:
parent
28940c6d18
commit
bc629c8b65
1
Makefile
1
Makefile
@ -457,6 +457,7 @@ test: qjs$(EXE)
|
||||
$(WINE) ./qjs$(EXE) tests/bug1301.js
|
||||
$(WINE) ./qjs$(EXE) tests/bug1302.js
|
||||
$(WINE) ./qjs$(EXE) tests/bug1305.js
|
||||
$(WINE) ./qjs$(EXE) tests/bug1296.js
|
||||
ifndef CONFIG_WIN32
|
||||
$(WINE) ./qjs$(EXE) tests/test_std.js
|
||||
endif
|
||||
|
||||
21
quickjs.c
21
quickjs.c
@ -58228,6 +58228,27 @@ static JSValue js_typed_array_constructor(JSContext *ctx,
|
||||
JS_FreeValue(ctx, buffer);
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
// Re-validate buffer after js_create_from_ctor which may have run JS code
|
||||
// that resized or detached the ArrayBuffer
|
||||
abuf = JS_VALUE_GET_OBJ(buffer)->u.array_buffer;
|
||||
if (abuf->detached) {
|
||||
JS_FreeValue(ctx, buffer);
|
||||
JS_FreeValue(ctx, obj);
|
||||
return JS_ThrowTypeErrorDetachedArrayBuffer(ctx);
|
||||
}
|
||||
if (offset > abuf->byte_length) {
|
||||
JS_FreeValue(ctx, buffer);
|
||||
JS_FreeValue(ctx, obj);
|
||||
return JS_ThrowRangeError(ctx, "invalid offset");
|
||||
}
|
||||
if (track_rab) {
|
||||
// Recalculate length for RAB-backed view
|
||||
len = (abuf->byte_length - offset) >> size_log2;
|
||||
} else if ((offset + (len << size_log2)) > abuf->byte_length) {
|
||||
JS_FreeValue(ctx, buffer);
|
||||
JS_FreeValue(ctx, obj);
|
||||
return JS_ThrowRangeError(ctx, "invalid length");
|
||||
}
|
||||
if (typed_array_init(ctx, obj, buffer, offset, len, track_rab)) {
|
||||
JS_FreeValue(ctx, obj);
|
||||
return JS_EXCEPTION;
|
||||
|
||||
13
tests/bug1296.js
Normal file
13
tests/bug1296.js
Normal file
@ -0,0 +1,13 @@
|
||||
import {assert} from "./assert.js"
|
||||
|
||||
const ab = new ArrayBuffer(10, { maxByteLength: 10 });
|
||||
function f() {
|
||||
return 1337;
|
||||
}
|
||||
const evil = f.bind();
|
||||
|
||||
Object.defineProperty(evil, "prototype", { get: () => {
|
||||
return ab.resize();
|
||||
} });
|
||||
let u8 = Reflect.construct(Uint8Array, [ab], evil);
|
||||
assert(u8.length == 0);
|
||||
Loading…
Reference in New Issue
Block a user