Conversation
|
Presumably we should take a consistent approach here across all of wasm2c? I believe we have calls to Can you also add a test case for this? Presumably |
| table->size = elements; | ||
| table->max_size = max_elements; | ||
| table->data = calloc(table->size, sizeof(WASM_RT_TABLE_ELEMENT_TYPE)); | ||
| if (elements != 0 && !table->data) { |
There was a problem hiding this comment.
Use table->size instead of elements here since that is what was passed to calloc.
| table->max_size = max_elements; | ||
| table->data = calloc(table->size, sizeof(WASM_RT_TABLE_ELEMENT_TYPE)); | ||
| if (elements != 0 && !table->data) { | ||
| table->size = table->max_size = 0; |
There was a problem hiding this comment.
Is there any point in this line if the next line is abort ? Maybe just remove it?
There was a problem hiding this comment.
@sbc100 I may follow up in a separate commit to rewrite this to a standard test here. I don't think we want to maintain a separate test tool .py for one test that will likely never get broken (i can also leave it in if you prefer)
2f0fe2f to
1b3a91c
Compare
There was a problem hiding this comment.
looks like the rebase is causing build failures.
@sxvncry If you are upto it, can you see if you add the failing wat file as a normal test like test/wasm2c/address-overflow.txt with the default test runner instead of a new runner tool? If this doesn't work for some reason, could you look into fixing your custom runner to pass the tests?
Alternately, if you have trouble with the test addition fix, you can submit just the code patch that you did earlier, and I can take over adding the test. (If you want to do this, please let me know)
|
Happy to defer to you on this one @shravanrn |
|
Thanks @shravanrn. Please feel free to take over the test addition and rewrite it as a standard test. The code patch itself is ready from my side. |
|
@sxvncry sounds good. |
Fixes #2854
PoC (same script attached to the issue): https://github.com/user-attachments/files/32163301/poc.sh
Summary
The wasm2c runtime table allocators (
wasm-rt-impl-tableops.inc, templatefor funcref/externref/exnref) never check the
calloc()result. Onallocation failure the table keeps the requested huge
sizewhiledatais NULL, so the bounds check
i < table->sizepasses for every index andgenerated code touches
table->data[i]atNULL + i*sizeof(element)withi up to ~2e9 — a guest read/write/control-flow-hijack primitive in host
memory (low 64 GiB of the address space).
The memory allocator in the same runtime already checks its calloc result
and aborts (
wasm-rt-mem-impl-helper.inc, from #2786); the table pathnever got the same treatment.
Root cause
wasm2c/wasm-rt-impl-tableops.incline 54:Trigger:
(table 2000000000 4000000000 funcref)→ 2e9 * 32 = 64 GBcalloc fails under memory pressure / address-space limit → broken
invariant.
Impact (poc.sh, 6/6 pass, unpatched HEAD)
NULL + 8192*32 = 0x40000; the host maps a callback struct there, the
guest function pointer lands in it and the host calls it.
table.getdistinguishes host memory contents at the sameaddress (
ref.is_nullleaks null-ness of 32-byte words across 0–64 GB).table.setcrashes the host deterministically.data=NULL size=2e9.Fix
Mirror the memory path: after
calloc, ifelements != 0anddataisNULL, reset
size/max_sizeto 0 andabort(). The size reset closesthe window even if the host installs a
WASM_RT_TRAPhandler thatintercepts the failure path. The
growpath already handles failurecorrectly — this patch makes
allocatefail closed too.