From 53d5d797ffc2c3336e6e2f954d0f65bad4885ab5 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Sun, 21 Jan 2024 21:56:41 +0000 Subject: [PATCH] [wasm64] Error on `-fsanitize=address` + wasm64 This chance also includes a couple of minor fixes to asan + memory64 that helped me to confirm that it really doesn't work yet. See #21177 --- .../sanitizer_common/sanitizer_emscripten.cpp | 2 ++ test/test_other.py | 4 ++++ tools/emscripten.py | 17 +++++++++++++++ tools/link.py | 21 +++++-------------- 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/system/lib/compiler-rt/lib/sanitizer_common/sanitizer_emscripten.cpp b/system/lib/compiler-rt/lib/sanitizer_common/sanitizer_emscripten.cpp index babc6793663a..c10dc0048a32 100644 --- a/system/lib/compiler-rt/lib/sanitizer_common/sanitizer_emscripten.cpp +++ b/system/lib/compiler-rt/lib/sanitizer_common/sanitizer_emscripten.cpp @@ -127,6 +127,8 @@ u64 MonotonicNanoTime() { return (u64)ts.tv_sec * (1000ULL * 1000 * 1000) + ts.tv_nsec; } +void GetMemoryProfile(fill_profile_f cb, uptr *stats) {} + } // namespace __sanitizer #endif diff --git a/test/test_other.py b/test/test_other.py index 9f935f2decfd..3e8c49fecd4d 100644 --- a/test/test_other.py +++ b/test/test_other.py @@ -14421,3 +14421,7 @@ def test_uuid(self): # "window.crypto.getRandomValues" self.assertContained(").randomBytes", js_out) self.assertContained("window.crypto.getRandomValues", js_out) + + def test_wasm64_no_asan(self): + err = self.expect_fail([EMCC, test_file('hello_world.c'), '-sMEMORY64', '-fsanitize=address']) + self.assertContained('error: MEMORY64 does not yet work with ASAN', err) diff --git a/tools/emscripten.py b/tools/emscripten.py index 24f9095f347d..a5a38a3b1439 100644 --- a/tools/emscripten.py +++ b/tools/emscripten.py @@ -37,6 +37,20 @@ logger = logging.getLogger('emscripten') +# helper functions for JS to call into C to do memory operations. these +# let us sanitize memory access from the JS side, by calling into C where +# it has been instrumented. +ASAN_C_HELPERS = [ + '_asan_c_load_1', '_asan_c_load_1u', + '_asan_c_load_2', '_asan_c_load_2u', + '_asan_c_load_4', '_asan_c_load_4u', + '_asan_c_load_f', '_asan_c_load_d', + '_asan_c_store_1', '_asan_c_store_1u', + '_asan_c_store_2', '_asan_c_store_2u', + '_asan_c_store_4', '_asan_c_store_4u', + '_asan_c_store_f', '_asan_c_store_d', +] + def compute_minimal_runtime_initializer_and_exports(post, exports, receiving): # Declare all exports out to global JS scope so that JS library functions can access them in a @@ -955,6 +969,9 @@ def create_pointer_conversion_wrappers(metadata): sym, sig = function.split(':') mapping[sym] = sig + for f in ASAN_C_HELPERS: + mapping[f] = '_p' + wrappers = ''' // Argument name here must shadow the `wasmExports` global so // that it is recognised by metadce and minify-import-export-names diff --git a/tools/link.py b/tools/link.py index 7072a18ab519..97882439c9eb 100644 --- a/tools/link.py +++ b/tools/link.py @@ -1546,21 +1546,7 @@ def check_memory_setting(setting): if not settings.UBSAN_RUNTIME: settings.UBSAN_RUNTIME = 2 - # helper functions for JS to call into C to do memory operations. these - # let us sanitize memory access from the JS side, by calling into C where - # it has been instrumented. - ASAN_C_HELPERS = [ - '_asan_c_load_1', '_asan_c_load_1u', - '_asan_c_load_2', '_asan_c_load_2u', - '_asan_c_load_4', '_asan_c_load_4u', - '_asan_c_load_f', '_asan_c_load_d', - '_asan_c_store_1', '_asan_c_store_1u', - '_asan_c_store_2', '_asan_c_store_2u', - '_asan_c_store_4', '_asan_c_store_4u', - '_asan_c_store_f', '_asan_c_store_d', - ] - - settings.REQUIRED_EXPORTS += ASAN_C_HELPERS + settings.REQUIRED_EXPORTS += emscripten.ASAN_C_HELPERS if settings.ASYNCIFY and not settings.ASYNCIFY_ONLY: # we do not want asyncify to instrument these helpers - they just access @@ -1572,7 +1558,7 @@ def check_memory_setting(setting): # do anything (as the user's list won't contain these functions), and if # we did add them, the pass would assert on incompatible lists, hence the # condition in the above if. - settings.ASYNCIFY_REMOVE += ASAN_C_HELPERS + settings.ASYNCIFY_REMOVE += emscripten.ASAN_C_HELPERS if settings.ASAN_SHADOW_SIZE != -1: diagnostics.warning('emcc', 'ASAN_SHADOW_SIZE is ignored and will be removed in a future release') @@ -1620,6 +1606,9 @@ def check_memory_setting(setting): # by SAFE_HEAP as a null pointer dereference. exit_with_error('ASan does not work with SAFE_HEAP') + if settings.MEMORY64: + exit_with_error('MEMORY64 does not yet work with ASAN') + if settings.USE_ASAN or settings.SAFE_HEAP: # ASan and SAFE_HEAP check address 0 themselves settings.CHECK_NULL_WRITES = 0