mirror of
https://github.com/bellard/quickjs.git
synced 2026-03-31 12:18:01 +00:00
fixed buffer overflow in Atomics with resizable typed arrays
This commit is contained in:
parent
16d6947b17
commit
46bd985b33
91
quickjs.c
91
quickjs.c
@ -58651,9 +58651,8 @@ typedef enum AtomicsOpEnum {
|
||||
ATOMICS_OP_LOAD,
|
||||
} AtomicsOpEnum;
|
||||
|
||||
static int js_atomics_get_ptr(JSContext *ctx,
|
||||
void **pptr,
|
||||
JSArrayBuffer **pabuf,
|
||||
static int js_atomics_get_ptr(JSContext *ctx, void **pptr,
|
||||
JSObject **pobj, uint64_t *pidx,
|
||||
int *psize_log2, JSClassID *pclass_id,
|
||||
JSValueConst obj, JSValueConst idx_val,
|
||||
int is_waitable)
|
||||
@ -58720,13 +58719,16 @@ static int js_atomics_get_ptr(JSContext *ctx,
|
||||
|
||||
size_log2 = typed_array_size_log2(p->class_id);
|
||||
ptr = p->u.array.u.uint8_ptr + ((uintptr_t)idx << size_log2);
|
||||
if (pabuf)
|
||||
*pabuf = abuf;
|
||||
|
||||
*pptr = ptr;
|
||||
if (pobj)
|
||||
*pobj = p;
|
||||
if (pidx)
|
||||
*pidx = idx;
|
||||
if (psize_log2)
|
||||
*psize_log2 = size_log2;
|
||||
if (pclass_id)
|
||||
*pclass_id = p->class_id;
|
||||
*pptr = ptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -58735,13 +58737,13 @@ static JSValue js_atomics_op(JSContext *ctx,
|
||||
int argc, JSValueConst *argv, int op)
|
||||
{
|
||||
int size_log2;
|
||||
uint64_t v, a, rep_val;
|
||||
uint64_t v, a, rep_val, idx;
|
||||
void *ptr;
|
||||
JSValue ret;
|
||||
JSClassID class_id;
|
||||
JSArrayBuffer *abuf;
|
||||
|
||||
if (js_atomics_get_ptr(ctx, &ptr, &abuf, &size_log2, &class_id,
|
||||
JSObject *p;
|
||||
|
||||
if (js_atomics_get_ptr(ctx, &ptr, &p, &idx, &size_log2, &class_id,
|
||||
argv[0], argv[1], 0))
|
||||
return JS_EXCEPTION;
|
||||
rep_val = 0;
|
||||
@ -58769,8 +58771,10 @@ static JSValue js_atomics_op(JSContext *ctx,
|
||||
rep_val = v32;
|
||||
}
|
||||
}
|
||||
if (abuf->detached)
|
||||
if (typed_array_is_oob(p))
|
||||
return JS_ThrowTypeErrorDetachedArrayBuffer(ctx);
|
||||
if (idx >= p->u.array.count)
|
||||
return JS_ThrowRangeError(ctx, "out-of-bound access");
|
||||
}
|
||||
|
||||
switch(op | (size_log2 << 3)) {
|
||||
@ -58881,48 +58885,53 @@ static JSValue js_atomics_store(JSContext *ctx,
|
||||
int size_log2;
|
||||
void *ptr;
|
||||
JSValue ret;
|
||||
JSArrayBuffer *abuf;
|
||||
|
||||
if (js_atomics_get_ptr(ctx, &ptr, &abuf, &size_log2, NULL,
|
||||
JSObject *p;
|
||||
uint64_t idx;
|
||||
int64_t v;
|
||||
|
||||
if (js_atomics_get_ptr(ctx, &ptr, &p, &idx, &size_log2, NULL,
|
||||
argv[0], argv[1], 0))
|
||||
return JS_EXCEPTION;
|
||||
if (size_log2 == 3) {
|
||||
int64_t v64;
|
||||
ret = JS_ToBigIntFree(ctx, JS_DupValue(ctx, argv[2]));
|
||||
if (JS_IsException(ret))
|
||||
return ret;
|
||||
if (JS_ToBigInt64(ctx, &v64, ret)) {
|
||||
if (JS_ToBigInt64(ctx, &v, ret)) {
|
||||
JS_FreeValue(ctx, ret);
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
if (abuf->detached)
|
||||
return JS_ThrowTypeErrorDetachedArrayBuffer(ctx);
|
||||
atomic_store((_Atomic(uint64_t) *)ptr, v64);
|
||||
} else {
|
||||
uint32_t v;
|
||||
uint32_t v32;
|
||||
/* XXX: spec, would be simpler to return the written value */
|
||||
ret = JS_ToIntegerFree(ctx, JS_DupValue(ctx, argv[2]));
|
||||
if (JS_IsException(ret))
|
||||
return ret;
|
||||
if (JS_ToUint32(ctx, &v, ret)) {
|
||||
if (JS_ToUint32(ctx, &v32, ret)) {
|
||||
JS_FreeValue(ctx, ret);
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
if (abuf->detached)
|
||||
return JS_ThrowTypeErrorDetachedArrayBuffer(ctx);
|
||||
switch(size_log2) {
|
||||
case 0:
|
||||
atomic_store((_Atomic(uint8_t) *)ptr, v);
|
||||
break;
|
||||
case 1:
|
||||
atomic_store((_Atomic(uint16_t) *)ptr, v);
|
||||
break;
|
||||
case 2:
|
||||
atomic_store((_Atomic(uint32_t) *)ptr, v);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
v = v32;
|
||||
}
|
||||
if (typed_array_is_oob(p))
|
||||
return JS_ThrowTypeErrorDetachedArrayBuffer(ctx);
|
||||
if (idx >= p->u.array.count)
|
||||
return JS_ThrowRangeError(ctx, "out-of-bound access");
|
||||
|
||||
switch(size_log2) {
|
||||
case 0:
|
||||
atomic_store((_Atomic(uint8_t) *)ptr, v);
|
||||
break;
|
||||
case 1:
|
||||
atomic_store((_Atomic(uint16_t) *)ptr, v);
|
||||
break;
|
||||
case 2:
|
||||
atomic_store((_Atomic(uint32_t) *)ptr, v);
|
||||
break;
|
||||
case 3:
|
||||
atomic_store((_Atomic(uint64_t) *)ptr, v);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -59005,9 +59014,10 @@ static JSValue js_atomics_wait(JSContext *ctx,
|
||||
int ret, size_log2, res;
|
||||
double d;
|
||||
|
||||
if (js_atomics_get_ptr(ctx, &ptr, NULL, &size_log2, NULL,
|
||||
if (js_atomics_get_ptr(ctx, &ptr, NULL, NULL, &size_log2, NULL,
|
||||
argv[0], argv[1], 2))
|
||||
return JS_EXCEPTION;
|
||||
/* 'argv[0]' is a SharedArrayBuffer so it cannot be detached nor reduced */
|
||||
if (size_log2 == 3) {
|
||||
if (JS_ToBigInt64(ctx, &v, argv[2]))
|
||||
return JS_EXCEPTION;
|
||||
@ -59083,8 +59093,9 @@ static JSValue js_atomics_notify(JSContext *ctx,
|
||||
void *ptr;
|
||||
JSAtomicsWaiter *waiter;
|
||||
JSArrayBuffer *abuf;
|
||||
|
||||
if (js_atomics_get_ptr(ctx, &ptr, &abuf, NULL, NULL, argv[0], argv[1], 1))
|
||||
JSObject *p;
|
||||
|
||||
if (js_atomics_get_ptr(ctx, &ptr, &p, NULL, NULL, NULL, argv[0], argv[1], 1))
|
||||
return JS_EXCEPTION;
|
||||
|
||||
if (JS_IsUndefined(argv[2])) {
|
||||
@ -59095,7 +59106,9 @@ static JSValue js_atomics_notify(JSContext *ctx,
|
||||
}
|
||||
|
||||
n = 0;
|
||||
abuf = p->u.typed_array->buffer->u.array_buffer;
|
||||
if (abuf->shared && count > 0) {
|
||||
/* 'argv[0]' is a SharedArrayBuffer so it cannot be detached nor reduced */
|
||||
pthread_mutex_lock(&js_atomics_mutex);
|
||||
init_list_head(&waiter_list);
|
||||
list_for_each_safe(el, el1, &js_atomics_waiter_list) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user