-
Notifications
You must be signed in to change notification settings - Fork 3.5k
UBSan function pointer mismatch reporting not working #26600
Description
Taking the example from
It generates a nice error in a native build:
$ clang-19 -fsanitize=undefined a.cpp
$ ./a.out
voidReturn: hello world
a.cpp:22:5: runtime error: call to function intReturn(char const*) through pointer to incorrect function type 'void (*)(const char *)'
(a.out+0x31b68): note: intReturn(char const*) defined here
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior a.cpp:22:5
intReturn: hello world
voidReturnNoParam:
However, in wasm it doesn't:
$ ./emcc a.cpp -g -fsanitize=undefined
$ nodejs a.out.js
voidReturn: hello world
wasm://wasm/a.out.wasm-00a00baa:1
RuntimeError: null function or function signature mismatch
at a.out.wasm.callFunctions(void (* const*)(char const*), unsigned long) (wasm://wasm/a.out.wasm-00a00baa:wasm-function[36]:0xdbb)
at a.out.wasm.__original_main (wasm://wasm/a.out.wasm-00a00baa:wasm-function[37]:0xee2)
at a.out.wasm.main (wasm://wasm/a.out.wasm-00a00baa:wasm-function[42]:0xfb4)
at a.out.js:545:12
at callMain (a.out.js:4310:15)
at doRun (a.out.js:4352:24)
at run (a.out.js:4362:5)
at removeRunDependency (a.out.js:742:7)
at receiveInstance (a.out.js:632:5)
at receiveInstantiationResult (a.out.js:648:12)
Node.js v22.22.0
UBSan just doesn't do anything here, and we get the low-level error.
I wonder if the issue is that UBSan checks this after the call, that is, each function prologue checks if it was indirect-called, and it knows its signature, and reports any mismatch. That seems plausible, and then it would not work in wasm since we trap before we reach that code. However, if so, then I'd expect our function pointer cast emulation to fix things, as it avoids the low-level trap, but UBSan's check should still be there (since we do this after UBSan runs), and it doesn't:
$ ./emcc a.cpp -g -fsanitize=undefined -sEMULATE_FUNCTION_POINTER_CASTS
$ nodejs a.out.js
voidReturn: hello world
intReturn: hello world
voidReturnNoParam:
The program just runs ok, with no report from UBSan despite the undefined behavior.
If we get UBSan working here, it could make debugging this a lot easier for people.