fixes memory leak in the emscripten page allocator (#25901)

The emscripten branch cast the descriptor address to the value type
EmscriptenMMapBlock instead of the pointer alias PEmscriptenMMapBlock,
so osAllocPages stored realSize/realPointer in a discarded local and
osDeallocPages reinterpreted the address integer as the descriptor
instead of dereferencing it -- calling munmap() with garbage that fails,
so freed pages are never returned. Freed huge chunks are also dropped
from the free list, leaking permanently. Affects wasm32 and wasm64.

Cast to PEmscriptenMMapBlock so both accesses go through memory.
This commit is contained in:
WyattBlue
2026-07-02 06:03:34 -04:00
committed by GitHub
parent a0e44d7aca
commit 8101c8d73b

View File

@@ -89,7 +89,7 @@ elif defined(emscripten) and not defined(StandaloneHeapSize):
var mmapDescrPos = cast[int](result) -% sizeof(EmscriptenMMapBlock)
var mmapDescr = cast[EmscriptenMMapBlock](mmapDescrPos)
var mmapDescr = cast[PEmscriptenMMapBlock](mmapDescrPos)
mmapDescr.realSize = realSize
mmapDescr.realPointer = realPointer
@@ -99,7 +99,7 @@ elif defined(emscripten) and not defined(StandaloneHeapSize):
proc osDeallocPages(p: pointer, size: int) {.inline.} =
var mmapDescrPos = cast[int](p) -% sizeof(EmscriptenMMapBlock)
var mmapDescr = cast[EmscriptenMMapBlock](mmapDescrPos)
var mmapDescr = cast[PEmscriptenMMapBlock](mmapDescrPos)
munmap(mmapDescr.realPointer, mmapDescr.realSize)
elif defined(genode) and not defined(StandaloneHeapSize):