wasm メモリ境界読み書きテスト#
手動で wasm モジュールを作成し、wat コードは以下の通りです:
- メモリ空間を宣言する
- メモリを書き込む関数と読み込む関数の 2 つを公開し、その後 js コードで呼び出す
(module
;;メモリを提供する必要があることを宣言
(import "env" "memory" (memory 1 2)) ;; 初期 1 ページ、最大 2 ページ
;; i32をメモリ[offset]に書き込む
(func (export "writeToMemory") (param i32) (param i32)
(i32.store
(local.get 0)
(local.get 1)
)
)
;; メモリ[offset]からi32を読み込む
(func (export "readFromMemory") (param i32) (result i32)
(i32.load
(local.get 0)
)
)
)
次に wasm モジュールにコンパイルします
wat2wasm memory_test.wat -o memory_test.wasm
js コードを作成します
const fs = require('fs');
(async () => {
const memory = new WebAssembly.Memory({ initial: 1, maximum: 2 });
const importObject = {
env: {
memory: memory
}
};
// wasmを読み込み、メモリを割り当てる
const wasmBuffer = fs.readFileSync('./memory_test.wasm');
const wasmModule = await WebAssembly.instantiate(wasmBuffer, importObject);
const { writeToMemory, readFromMemory} = wasmModule.instance.exports;
const inBoundsOffset = 65532; // 正常なオフセット
const outOfBoundsOffset = 70000; // 境界外オフセット
// 正常な書き込みと読み取りをテスト
writeToMemory(inBoundsOffset, 123456);
console.log("読み取ったデータ:", readFromMemory(inBoundsOffset));
try {
// 👇 境界外書き込みを試みる
console.log("境界外書き込みデータを試みる");
writeToMemory(outOfBoundsOffset, 999);
} catch (err) {
console.error("境界外書き込みエラー:", err.message);
console.log(err);
}
try {
// 👇 境界外読み取りを試みる
console.log("境界外読み取りデータを試みる");
console.log(readFromMemory(outOfBoundsOffset));
} catch (err) {
console.error("境界外読み取りエラー:", err.message);
console.log(err);
}
})();
実行結果から、エラーが発生することがわかります
❯ node main.js
読み取ったデータ: 123456
境界外書き込みデータを試みる
境界外書き込みエラー: memory access out of bounds
RuntimeError: memory access out of bounds
at wasm://wasm/488cc87e:wasm-function[0]:0x59
at /Users/rayepeng/Documents/code/wasm-memory-test/main.js:26:5
境界外読み取りデータを試みる
境界外読み取りエラー: memory access out of bounds
RuntimeError: memory access out of bounds
at wasm://wasm/488cc87e:wasm-function[1]:0x61
at /Users/rayepeng/Documents/code/wasm-memory-test/main.js:35:17