Bug 1642940 - Separate the validation and runtime memory limit checks. r=lth

This commit separates the validation limit defined by the core spec and the
implementation runtime limit defined by the JS-API spec. The exception
generated for the runtime check is a WebAssembly.RuntimeError as decided upon
upstream.

Additionally, there is no longer the concept of an 'initial' limit, so code
is updated to reflect this.

Differential Revision: https://phabricator.services.mozilla.com/D80138
This commit is contained in:
Ryan Hunt 2020-06-23 23:03:10 +00:00
Родитель 5fcbd2d352
Коммит b522b98a15
7 изменённых файлов: 19 добавлений и 14 удалений

Просмотреть файл

@ -412,6 +412,7 @@ MSG_DEF(JSMSG_WASM_OUT_OF_BOUNDS, 0, JSEXN_WASMRUNTIMEERROR, "index out of
MSG_DEF(JSMSG_WASM_UNALIGNED_ACCESS, 0, JSEXN_WASMRUNTIMEERROR, "unaligned memory access")
MSG_DEF(JSMSG_WASM_WAKE_OVERFLOW, 0, JSEXN_WASMRUNTIMEERROR, "too many woken agents")
MSG_DEF(JSMSG_WASM_DEREF_NULL, 0, JSEXN_WASMRUNTIMEERROR, "dereferencing null pointer")
MSG_DEF(JSMSG_WASM_MEM_IMP_LIMIT, 0, JSEXN_WASMRUNTIMEERROR, "too many memory pages")
MSG_DEF(JSMSG_WASM_BAD_RANGE , 2, JSEXN_RANGEERR, "bad {0} {1}")
MSG_DEF(JSMSG_WASM_BAD_GROW, 1, JSEXN_RANGEERR, "failed to grow {0}")
MSG_DEF(JSMSG_WASM_TABLE_OUT_OF_BOUNDS, 0, JSEXN_WASMRUNTIMEERROR, "table index out of bounds")

Просмотреть файл

@ -687,7 +687,7 @@ static bool CreateSpecificWasmBuffer(
// wasm::PageSize == 0
if (!useHugeMemory &&
clampedMaxSize.value() >= (UINT32_MAX - wasm::PageSize)) {
uint64_t clamp = (wasm::MaxMemoryMaximumPages - 2) * wasm::PageSize;
uint64_t clamp = (wasm::MaxMemoryLimitField - 2) * wasm::PageSize;
MOZ_ASSERT(clamp < UINT32_MAX);
MOZ_ASSERT(initialSize <= clamp);
clampedMaxSize = Some(clamp);
@ -806,8 +806,6 @@ bool js::CreateWasmBuffer(JSContext* cx, const wasm::Limits& memory,
MutableHandleArrayBufferObjectMaybeShared buffer) {
MOZ_ASSERT(memory.initial % wasm::PageSize == 0);
MOZ_RELEASE_ASSERT(cx->wasmHaveSignalHandlers);
MOZ_RELEASE_ASSERT((memory.initial / wasm::PageSize) <=
wasm::MaxMemoryInitialPages);
MOZ_RELEASE_ASSERT(memory.initial <= ArrayBufferObject::MaxBufferByteLength);
static_assert(ArrayBufferObject::MaxBufferByteLength <= UINT32_MAX,
"wasm memory uses uint32_t and is limited by"

Просмотреть файл

@ -859,7 +859,8 @@ static const unsigned MaxParams = 1000;
// `env->funcMaxResults()` to get the correct value for a module.
static const unsigned MaxResults = 1000;
static const unsigned MaxStructFields = 1000;
static const unsigned MaxMemoryMaximumPages = 65536;
static const unsigned MaxMemoryLimitField = 65536;
static const unsigned MaxMemoryPages = 16384;
static const unsigned MaxStringBytes = 100000;
static const unsigned MaxModuleBytes = 1024 * 1024 * 1024;
static const unsigned MaxFunctionBytes = 7654321;
@ -868,7 +869,6 @@ static const unsigned MaxFunctionBytes = 7654321;
static const unsigned MaxTableInitialLength = 10000000;
static const unsigned MaxBrTableElems = 1000000;
static const unsigned MaxMemoryInitialPages = 16384;
static const unsigned MaxCodeSectionBytes = MaxModuleBytes;
static const unsigned MaxResultsForJitEntry = 1;
static const unsigned MaxResultsForJitExit = 1;

Просмотреть файл

@ -2058,8 +2058,14 @@ bool WasmMemoryObject::construct(JSContext* cx, unsigned argc, Value* vp) {
RootedObject obj(cx, &args[0].toObject());
Limits limits;
if (!GetLimits(cx, obj, MaxMemoryInitialPages, MaxMemoryMaximumPages,
"Memory", &limits, Shareable::True)) {
if (!GetLimits(cx, obj, MaxMemoryLimitField, MaxMemoryLimitField, "Memory",
&limits, Shareable::True)) {
return false;
}
if (limits.initial > MaxMemoryPages) {
JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
JSMSG_WASM_MEM_IMP_LIMIT);
return false;
}

Просмотреть файл

@ -768,6 +768,12 @@ bool Module::instantiateMemory(JSContext* cx,
} else {
MOZ_ASSERT(!metadata().isAsmJS());
if (declaredMin / PageSize > MaxMemoryPages) {
JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
JSMSG_WASM_MEM_IMP_LIMIT);
return false;
}
RootedArrayBufferObjectMaybeShared buffer(cx);
Limits l(declaredMin, declaredMax,
declaredShared ? Shareable::True : Shareable::False);

Просмотреть файл

@ -45,12 +45,6 @@ using mozilla::MakeEnumeratedRange;
# endif
#endif
// More sanity checks.
static_assert(MaxMemoryInitialPages <=
ArrayBufferObject::MaxBufferByteLength / PageSize,
"Memory sizing constraint");
// All plausible targets must be able to do at least IEEE754 double
// loads/stores, hence the lower limit of 8. Some Intel processors support
// AVX-512 loads/stores, hence the upper limit of 64.

Просмотреть файл

@ -2002,7 +2002,7 @@ static bool DecodeMemoryLimits(Decoder& d, ModuleEnvironment* env) {
return false;
}
if (memory.initial > MaxMemoryInitialPages) {
if (memory.initial > MaxMemoryLimitField) {
return d.fail("initial memory size too big");
}