Changeset 224122 in webkit


Ignore:
Timestamp:
Oct 27, 2017 11:42:27 AM (6 years ago)
Author:
jfbastien@apple.com
Message:

WebAssembly: update arbitrary limits to what browsers use
https://bugs.webkit.org/show_bug.cgi?id=178946
<rdar://problem/34257412>
<rdar://problem/34501154>

Reviewed by Saam Barati.

https://github.com/WebAssembly/design/issues/1138 discusses the
arbitrary function size limit, which it turns out Chrome and
Firefox didn't enforce. We didn't use it because it was
ridiculously low and actual programs ran into that limit (bummer
for Edge which just shipped it...). Now that we agree on a high
arbitrary program limit, let's update it! While I'm doing this
there are a few other spots that I polished to use Checked or
better check limits overall.

  • wasm/WasmB3IRGenerator.cpp:

(JSC::Wasm::B3IRGenerator::addLocal):

  • wasm/WasmFormat.cpp:

(JSC::Wasm::Segment::create):

  • wasm/WasmFunctionParser.h:

(JSC::Wasm::FunctionParser<Context>::parse):

  • wasm/WasmInstance.cpp:
  • wasm/WasmLimits.h:
  • wasm/WasmModuleParser.cpp:

(JSC::Wasm::ModuleParser::parseGlobal):
(JSC::Wasm::ModuleParser::parseCode):
(JSC::Wasm::ModuleParser::parseData):

  • wasm/WasmSignature.h:

(JSC::Wasm::Signature::allocatedSize):

  • wasm/WasmTable.cpp:

(JSC::Wasm::Table::Table):

  • wasm/js/JSWebAssemblyTable.cpp:

(JSC::JSWebAssemblyTable::JSWebAssemblyTable):
(JSC::JSWebAssemblyTable::grow):

Location:
trunk/Source/JavaScriptCore
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r224072 r224122  
     12017-10-27  JF Bastien  <jfbastien@apple.com>
     2
     3        WebAssembly: update arbitrary limits to what browsers use
     4        https://bugs.webkit.org/show_bug.cgi?id=178946
     5        <rdar://problem/34257412>
     6        <rdar://problem/34501154>
     7
     8        Reviewed by Saam Barati.
     9
     10        https://github.com/WebAssembly/design/issues/1138 discusses the
     11        arbitrary function size limit, which it turns out Chrome and
     12        Firefox didn't enforce. We didn't use it because it was
     13        ridiculously low and actual programs ran into that limit (bummer
     14        for Edge which just shipped it...). Now that we agree on a high
     15        arbitrary program limit, let's update it! While I'm doing this
     16        there are a few other spots that I polished to use Checked or
     17        better check limits overall.
     18
     19        * wasm/WasmB3IRGenerator.cpp:
     20        (JSC::Wasm::B3IRGenerator::addLocal):
     21        * wasm/WasmFormat.cpp:
     22        (JSC::Wasm::Segment::create):
     23        * wasm/WasmFunctionParser.h:
     24        (JSC::Wasm::FunctionParser<Context>::parse):
     25        * wasm/WasmInstance.cpp:
     26        * wasm/WasmLimits.h:
     27        * wasm/WasmModuleParser.cpp:
     28        (JSC::Wasm::ModuleParser::parseGlobal):
     29        (JSC::Wasm::ModuleParser::parseCode):
     30        (JSC::Wasm::ModuleParser::parseData):
     31        * wasm/WasmSignature.h:
     32        (JSC::Wasm::Signature::allocatedSize):
     33        * wasm/WasmTable.cpp:
     34        (JSC::Wasm::Table::Table):
     35        * wasm/js/JSWebAssemblyTable.cpp:
     36        (JSC::JSWebAssemblyTable::JSWebAssemblyTable):
     37        (JSC::JSWebAssemblyTable::grow):
     38
    1392017-10-26  Michael Saboff  <msaboff@apple.com>
    240
  • trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp

    r224020 r224122  
    512512auto B3IRGenerator::addLocal(Type type, uint32_t count) -> PartialResult
    513513{
    514     WASM_COMPILE_FAIL_IF(!m_locals.tryReserveCapacity(m_locals.size() + count), "can't allocate memory for ", m_locals.size() + count, " locals");
     514    Checked<uint32_t, RecordOverflow> totalBytesChecked = count;
     515    totalBytesChecked += m_locals.size();
     516    uint32_t totalBytes;
     517    WASM_COMPILE_FAIL_IF((totalBytesChecked.safeGet(totalBytes) == CheckedState::DidOverflow) || !m_locals.tryReserveCapacity(totalBytes), "can't allocate memory for ", totalBytes, " locals");
    515518
    516519    for (uint32_t i = 0; i < count; ++i) {
  • trunk/Source/JavaScriptCore/wasm/WasmFormat.cpp

    r216597 r224122  
    3131
    3232#include "WasmMemory.h"
     33#include <wtf/CheckedArithmetic.h>
    3334#include <wtf/FastMalloc.h>
    3435
     
    3738Segment* Segment::create(I32InitExpr offset, uint32_t sizeInBytes)
    3839{
    39     auto allocated = tryFastCalloc(sizeof(Segment) + sizeInBytes, 1);
     40    Checked<uint32_t, RecordOverflow> totalBytesChecked = sizeInBytes;
     41    totalBytesChecked += sizeof(Segment);
     42    uint32_t totalBytes;
     43    if (totalBytesChecked.safeGet(totalBytes) == CheckedState::DidOverflow)
     44        return nullptr;
     45    auto allocated = tryFastCalloc(totalBytes, 1);
    4046    Segment* segment;
    4147    if (!allocated.getValue(segment))
  • trunk/Source/JavaScriptCore/wasm/WasmFunctionParser.h

    r220894 r224122  
    113113    WASM_PARSER_FAIL_IF(!m_context.addArguments(m_signature), "can't add ", m_signature.argumentCount(), " arguments to Function");
    114114    WASM_PARSER_FAIL_IF(!parseVarUInt32(localCount), "can't get local count");
    115     WASM_PARSER_FAIL_IF(localCount == std::numeric_limits<uint32_t>::max(), "Function section's local count is too big ", localCount);
     115    WASM_PARSER_FAIL_IF(localCount > maxFunctionLocals, "Function section's local count is too big ", localCount, " maximum ", maxFunctionLocals);
    116116
    117117    for (uint32_t i = 0; i < localCount; ++i) {
     
    120120
    121121        WASM_PARSER_FAIL_IF(!parseVarUInt32(numberOfLocals), "can't get Function's number of locals in group ", i);
    122         WASM_PARSER_FAIL_IF(numberOfLocals == std::numeric_limits<uint32_t>::max(), "Function section's ", i, "th local group count is too big ", numberOfLocals);
     122        WASM_PARSER_FAIL_IF(numberOfLocals > maxFunctionLocals, "Function section's ", i, "th local group count is too big ", numberOfLocals, " maximum ", maxFunctionLocals);
    123123        WASM_PARSER_FAIL_IF(!parseValueType(typeOfLocal), "can't get Function local's type in group ", i);
    124124        WASM_TRY_ADD_TO_CONTEXT(addLocal(typeOfLocal, numberOfLocals));
  • trunk/Source/JavaScriptCore/wasm/WasmInstance.cpp

    r224020 r224122  
    2727#include "WasmInstance.h"
    2828
     29#if ENABLE(WEBASSEMBLY)
     30
    2931#include "Register.h"
    3032#include "WasmModuleInformation.h"
    31 
    32 #if ENABLE(WEBASSEMBLY)
     33#include <wtf/CheckedArithmetic.h>
    3334
    3435namespace JSC { namespace Wasm {
     
    3738size_t globalMemoryByteSize(Module& module)
    3839{
    39     return module.moduleInformation().globals.size() * sizeof(Register);
     40    return (Checked<size_t>(module.moduleInformation().globals.size()) * sizeof(Register)).unsafeGet();
    4041}
    4142}
  • trunk/Source/JavaScriptCore/wasm/WasmLimits.h

    r216921 r224122  
    4747constexpr size_t maxStringSize = 100000;
    4848constexpr size_t maxModuleSize = 1024 * 1024 * 1024;
     49constexpr size_t maxFunctionSize = 7654321;
     50constexpr size_t maxFunctionLocals = 50000;
    4951constexpr size_t maxFunctionParams = 1000;
    5052
  • trunk/Source/JavaScriptCore/wasm/WasmModuleParser.cpp

    r223738 r224122  
    341341    WASM_PARSER_FAIL_IF(!parseVarUInt32(globalCount), "can't get Global section's count");
    342342    WASM_PARSER_FAIL_IF(globalCount > maxGlobals, "Global section's count is too big ", globalCount, " maximum ", maxGlobals);
    343     WASM_PARSER_FAIL_IF(!m_info->globals.tryReserveCapacity(globalCount + m_info->firstInternalGlobal), "can't allocate memory for ", globalCount + m_info->firstInternalGlobal, " globals");
     343    size_t totalBytes = globalCount + m_info->firstInternalGlobal;
     344    WASM_PARSER_FAIL_IF((static_cast<uint32_t>(totalBytes) < globalCount) || !m_info->globals.tryReserveCapacity(totalBytes), "can't allocate memory for ", totalBytes, " globals");
    344345
    345346    for (uint32_t globalIndex = 0; globalIndex < globalCount; ++globalIndex) {
     
    475476        WASM_PARSER_FAIL_IF(functionSize > length(), "Code function's size ", functionSize, " exceeds the module's size ", length());
    476477        WASM_PARSER_FAIL_IF(functionSize > length() - m_offset, "Code function's size ", functionSize, " exceeds the module's remaining size", length() - m_offset);
    477         WASM_PARSER_FAIL_IF(functionSize > std::numeric_limits<uint32_t>::max(), "Code function's size ", functionSize, " is too big");
     478        WASM_PARSER_FAIL_IF(functionSize > maxFunctionSize, "Code function's size ", functionSize, " is too big");
    478479
    479480        m_info->functionLocationInBinary[i].start = m_offset;
     
    574575        WASM_PARSER_FAIL_IF(initExprType != I32, segmentNumber, "th Data segment's init_expr must produce an i32");
    575576        WASM_PARSER_FAIL_IF(!parseVarUInt32(dataByteLength), "can't get ", segmentNumber, "th Data segment's data byte length");
    576         WASM_PARSER_FAIL_IF(dataByteLength == std::numeric_limits<uint32_t>::max(), segmentNumber, "th Data segment's data byte length is too big ", dataByteLength);
     577        WASM_PARSER_FAIL_IF(dataByteLength > maxModuleSize, segmentNumber, "th Data segment's data byte length is too big ", dataByteLength, " maximum ", maxModuleSize);
    577578
    578579        Segment* segment = Segment::create(makeI32InitExpr(initOpcode, initExprBits), dataByteLength);
  • trunk/Source/JavaScriptCore/wasm/WasmSignature.h

    r223738 r224122  
    3232#include <cstdint>
    3333#include <cstring>
     34#include <wtf/CheckedArithmetic.h>
    3435#include <wtf/HashMap.h>
    3536#include <wtf/HashTraits.h>
     
    6566    }
    6667    Type* storage(SignatureArgCount i) const { return const_cast<Signature*>(this)->storage(i); }
    67     static size_t allocatedSize(SignatureArgCount argCount)
     68    static size_t allocatedSize(Checked<SignatureArgCount> argCount)
    6869    {
    69         return sizeof(Signature) + (s_retCount + argCount) * sizeof(Type);
     70        return (sizeof(Signature) + (s_retCount + argCount) * sizeof(Type)).unsafeGet();
    7071    }
    7172
  • trunk/Source/JavaScriptCore/wasm/WasmTable.cpp

    r224020 r224122  
    5555    // FIXME: It might be worth trying to pre-allocate maximum here. The spec recommends doing so.
    5656    // But for now, we're not doing that.
    57     m_functions = MallocPtr<Wasm::CallableFunction>::malloc(sizeof(Wasm::CallableFunction) * static_cast<size_t>(size()));
    58     m_instances = MallocPtr<Instance*>::malloc(sizeof(Instance*) * static_cast<size_t>(size()));
     57    m_functions = MallocPtr<Wasm::CallableFunction>::malloc((sizeof(Wasm::CallableFunction) * Checked<size_t>(size())).unsafeGet());
     58    m_instances = MallocPtr<Instance*>::malloc((sizeof(Instance*) * Checked<size_t>(size())).unsafeGet());
    5959    for (uint32_t i = 0; i < size(); ++i) {
    6060        new (&m_functions.get()[i]) CallableFunction();
  • trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.cpp

    r224020 r224122  
    3131#include "JSCInlines.h"
    3232#include "JSWebAssemblyInstance.h"
     33#include <wtf/CheckedArithmetic.h>
    3334
    3435namespace JSC {
     
    6263    // FIXME: It might be worth trying to pre-allocate maximum here. The spec recommends doing so.
    6364    // But for now, we're not doing that.
    64     m_jsFunctions = MallocPtr<WriteBarrier<JSObject>>::malloc(sizeof(WriteBarrier<JSObject>) * static_cast<size_t>(size()));
     65    m_jsFunctions = MallocPtr<WriteBarrier<JSObject>>::malloc((sizeof(WriteBarrier<JSObject>) * Checked<size_t>(size())).unsafeGet());
    6566    for (uint32_t i = 0; i < size(); ++i)
    6667        new(&m_jsFunctions.get()[i]) WriteBarrier<JSObject>();
     
    101102
    102103    size_t newSize = grew.value();
    103     m_jsFunctions.realloc(sizeof(WriteBarrier<JSObject>) * newSize);
     104    m_jsFunctions.realloc((sizeof(WriteBarrier<JSObject>) * Checked<size_t>(newSize)).unsafeGet());
    104105
    105106    for (size_t i = oldSize; i < newSize; ++i)
Note: See TracChangeset for help on using the changeset viewer.