Caching a Uint8Array of wasm.memory.buffer across calls to WebAssembly.instanitate causes a use-after-free in the WebAssembly::MemoryInstance.
This is easy to reproduce by inverting this patch to the WebAssembly-instantiate test:
diff --git a/Tests/LibWeb/Text/input/Wasm/WebAssembly-instantiate.html b/Tests/LibWeb/Text/input/Wasm/WebAssembly-instantiate.html
index 7f4593208ad..70a26d769d8 100644
--- a/Tests/LibWeb/Text/input/Wasm/WebAssembly-instantiate.html
+++ b/Tests/LibWeb/Text/input/Wasm/WebAssembly-instantiate.html
@@ -9,13 +9,8 @@
cachedTextDecoder.decode();
- let cachedUint8Memory0 = null;
-
function getUint8Memory0() {
- if (cachedUint8Memory0 === null || cachedUint8Memory0.byteLength === 0) {
- cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer);
- }
- return cachedUint8Memory0;
+ return new Uint8Array(wasm.memory.buffer);
}
function getStringFromWasm0(ptr, len) {
It seems like the WebAssembly code in LibWeb or LibWasm assumes that instantiating multiple modules means it's okay to invalidate any iterators into the WebAssembly memory.
However, JavaScript can violate this assumption. As this can cause writes or reads to arbitrary used-after-free'd memory in the native C++ heap, this is a pretty bad security issue.
Pay now to fund the work behind this issue.
Get updates on progress being made.
Maintainer is rewarded once the issue is completed.
You're funding impactful open source efforts
You want to contribute to this effort
You want to get funding like this too