Skip to content

Commit 5cb0e51

Browse files
maleadtvtjnash
andauthored
build: ASAN fixes for glibc (#51755)
For the `sigsetjmp` bypass; looks like glibc removed the `__libc_siglongjmp` symbol in glibc 2.34, so change to using the approach taking by our `dlopen` wrapper instead. Adopts topolarity's fixes from #50170 Resolves #47698 Co-authored-by: Jameson Nash <[email protected]>
1 parent 7327a8f commit 5cb0e51

File tree

3 files changed

+22
-5
lines changed

3 files changed

+22
-5
lines changed

src/dlload.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ JL_DLLEXPORT JL_NO_SANITIZE void *jl_dlopen(const char *filename, unsigned flags
188188
dlopen = (dlopen_prototype*)dlsym(RTLD_NEXT, "dlopen");
189189
if (!dlopen)
190190
return NULL;
191-
void *libdl_handle = dlopen("libdl.so", RTLD_NOW | RTLD_NOLOAD);
191+
void *libdl_handle = dlopen("libdl.so.2", RTLD_NOW | RTLD_NOLOAD);
192192
assert(libdl_handle);
193193
dlopen = (dlopen_prototype*)dlsym(libdl_handle, "dlopen");
194194
dlclose(libdl_handle);

src/julia.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2287,10 +2287,9 @@ void (ijl_longjmp)(jmp_buf _Buf, int _Value);
22872287
#define jl_setjmp_name "sigsetjmp"
22882288
#endif
22892289
#define jl_setjmp(a,b) sigsetjmp(a,b)
2290-
#if defined(_COMPILER_ASAN_ENABLED_) && __GLIBC__
2291-
// Bypass the ASAN longjmp wrapper - we're unpoisoning the stack ourselves.
2292-
JL_DLLIMPORT int __attribute__ ((nothrow)) (__libc_siglongjmp)(jl_jmp_buf buf, int val);
2293-
#define jl_longjmp(a,b) __libc_siglongjmp(a,b)
2290+
#if defined(_COMPILER_ASAN_ENABLED_) && defined(__GLIBC__)
2291+
extern void (*real_siglongjmp)(jmp_buf _Buf, int _Value);
2292+
#define jl_longjmp(a,b) real_siglongjmp(a,b)
22942293
#else
22952294
#define jl_longjmp(a,b) siglongjmp(a,b)
22962295
#endif

src/task.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@ extern "C" {
4242
#endif
4343

4444
#if defined(_COMPILER_ASAN_ENABLED_)
45+
#if __GLIBC__
46+
#include <dlfcn.h>
47+
// Bypass the ASAN longjmp wrapper - we are unpoisoning the stack ourselves,
48+
// since ASAN normally unpoisons far too much.
49+
// c.f. interceptor in jl_dlopen as well
50+
void (*real_siglongjmp)(jmp_buf _Buf, int _Value) = NULL;
51+
#endif
4552
static inline void sanitizer_start_switch_fiber(jl_ptls_t ptls, jl_task_t *from, jl_task_t *to) {
4653
if (to->copy_stack)
4754
__sanitizer_start_switch_fiber(&from->ctx.asan_fake_stack, (char*)ptls->stackbase-ptls->stacksize, ptls->stacksize);
@@ -1226,6 +1233,17 @@ void jl_init_tasks(void) JL_GC_DISABLED
12261233
exit(1);
12271234
}
12281235
#endif
1236+
#if defined(_COMPILER_ASAN_ENABLED_) && __GLIBC__
1237+
void *libc_handle = dlopen("libc.so.6", RTLD_NOW | RTLD_NOLOAD);
1238+
if (libc_handle) {
1239+
*(void**)&real_siglongjmp = dlsym(libc_handle, "siglongjmp");
1240+
dlclose(libc_handle);
1241+
}
1242+
if (real_siglongjmp == NULL) {
1243+
jl_safe_printf("failed to get real siglongjmp\n");
1244+
exit(1);
1245+
}
1246+
#endif
12291247
}
12301248

12311249
#if defined(_COMPILER_ASAN_ENABLED_)

0 commit comments

Comments
 (0)