← All issues

[Memory64] Wasm table import가 address type 일치 여부를 확인하지 않는 문제

Wasm table linking checked type, size, and max — everything but the address width.

Component: JSC WebAssembly | 862994e

WebAssembly의 Memory64 proposal은 table(그리고 memory)을 i32 또는 i64 address로 인덱싱할 수 있게 합니다. Address width가 offset 연산과 bounds check에 영향을 주기 때문에, JIT와 interpreter는 table이 어떤 address type을 선언했는지에 따라 call_indirect, table.get/table.set 등에 대해 서로 다른 indexing code를 생성합니다. Import validation은 원래 module이 정적으로 선언한 assumption과 일치하는 table에 대해서만 동작하도록 보장하는 경계 역할을 해야 합니다.

Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp

if (!Wasm::isSubtype(actualType, expectedType) || !Wasm::isSubtype(expectedType, actualType))
return exception(createJSWebAssemblyLinkError(globalObject, vm, importFailMessage(import, "Table import"_s, "provided a 'type' that is wrong"_s)));
 
+ if (table->table()->addressType() != moduleInformation.tables[import.kindIndex].addressType())
+ return exception(createJSWebAssemblyLinkError(globalObject, vm, importFailMessage(import, "Table import"_s, "provided an 'address' that is different from the module's declared 'address' import table attribute"_s)));
+
// ii. Append v to tables.
// iii. Append v.[[Table]] to imports.
m_instance->setTable(vm, import.kindIndex, table);

기존 table import linking은 element type, initial size, maximum size는 검증했지만, 제공된 table의 addressType()을 module이 선언한 import addressType()과 비교하는 절차는 없었습니다. 패치는 이 cross-check를 추가해 mismatch 시 LinkError를 던지도록 했습니다. 이제 i32 table은 table64 import를 충족시킬 수 없으며, 반대의 경우도 마찬가지입니다.

이 check가 없으면, 64-bit table index를 전제로 컴파일된 module이 32-bit indexing 내부 구조를 가진 table object와 link될 수 있었습니다. 한쪽 address width를 전제로 생성된 index/bounds-check code가 실제로는 다른 address width로 구성된 table을 대상으로 실행되는 상황이 가능해집니다. Wasm linking 경계에서 발생하는 address-width confusion으로, table addressing에 적용된 type-confusion 유형에 해당합니다.