Created attachment 12217 [details] Possible fix Hello, jemalloc [0] is a malloc alternative that makes calls to `clock_gettime` in order to do memory profiling (and possibly other reasons). This means that uses of malloc [1] which happen before VDSO is setup will access invalid memory. [0] https://github.com/jemalloc/jemalloc [1] such as the ones in _dl_get_origin and _dl_new_object ### Minimal error ```bash [eochoa@osprey1 temp]$ cat a.c #include <stdlib.h> int main( int argc, char **argv ) { malloc(0); } [eochoa@osprey1 temp]$ gcc -O0 -g a.c -ljemalloc -lpthread -static [eochoa@osprey1 temp]$ ./a.out Bus error (core dumped) ``` Please make sure * you are running on an aarch64 machine * and that either glibc 2.29 is installed or you are linking against glibc 2.29 like so: ``` [eochoa@osprey1 temp]$ gcc -O0 -g a.c -ljemalloc -lpthread -static /path/to/libc.a ``` ### Stack trace Using gdb, I found the stack trace when SIGBUS was sent. Two interesting things to note is that the error is triggered when `__clock_gettime` is called and very early during the program, during `__libc_init_first` . ``` #0 0x5efaf6adad3c47c6 in ?? () #1 0x00000000004cb914 in __clock_gettime (clock_id=6, tp=0xffffffffc400) at ../sysdeps/unix/sysv/linux/clock_gettime.c:33 #2 0x0000000000470b6c in nstime_get (time=0xffff80006b80) at src/nstime.c:119 #3 0x0000000000470bb8 in nstime_update_impl (time=0xffff80006b80) at src/nstime.c:160 #4 0x000000000042238c in arena_decay_reinit (decay=0xffff80006ab8, decay_ms=10000) at src/arena.c:672 #5 0x00000000004224b0 in arena_decay_init (decay=0xffff80006ab8, decay_ms=10000, stats=0xffff80000df0) at src/arena.c:693 #6 0x0000000000426298 in je_arena_new (tsdn=0x0, ind=0, extent_hooks=0x508200 <je_extent_hooks_default>) at src/arena.c:2043 #7 0x0000000000409fec in arena_init_locked (tsdn=0x0, ind=0, extent_hooks=0x508200 <je_extent_hooks_default>) at src/jemalloc.c:340 #8 0x000000000040a0b0 in je_arena_init (tsdn=0x0, ind=0, extent_hooks=0x508200 <je_extent_hooks_default>) at src/jemalloc.c:368 #9 0x000000000040f3a8 in malloc_init_hard_a0_locked () at src/jemalloc.c:1553 #10 0x000000000040fb04 in malloc_init_hard () at src/jemalloc.c:1750 #11 0x0000000000409b90 in malloc_init () at src/jemalloc.c:223 #12 0x0000000000410a88 in imalloc_init_check (sopts=0xffffffffe128, dopts=0xffffffffe0f0) at src/jemalloc.c:2229 #13 0x0000000000410bf4 in imalloc (sopts=0xffffffffe128, dopts=0xffffffffe0f0) at src/jemalloc.c:2260 #14 0x0000000000410d58 in je_malloc_default (size=19) at src/jemalloc.c:2289 #15 0x0000000000410ff8 in malloc (size=19) at src/jemalloc.c:2332 #16 0x00000000004f221c in _dl_get_origin () at ../sysdeps/unix/sysv/linux/generic/dl-origin.c:51 #17 0x00000000004ce6a4 in _dl_non_dynamic_init () at dl-support.c:308 #18 0x00000000004cf528 in __libc_init_first (argc=argc@entry=2, argv=argv@entry=0xfffffffff438, envp=0xfffffffff450) at ../csu/init-first.c:74 #19 0x00000000004b03ac in __libc_start_main (main=0x4006c4 <main>, argc=2, argv=0xfffffffff438, init=0x4b0840 <__libc_csu_init>, fini=0x4b0920 <__libc_csu_fini>, rtld_fini=0x0, stack_end=<optimized out>) at ../csu/libc-start.c:244 #20 0x000000000040058c in _start () at ../sysdeps/aarch64/start.S:92 ``` ### Bisecting glibc I did a git bisect from glibc 2.28 to glibc 2.29 and found [the offending commit](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=979cfed05d0ee5a9d81d310ea1eb2d590739e36b;hp=ce035c6e909ad20ef2fe13c92eab4e69f6495b61) Which enables VDSO for static linking. Since `clock_gettime` is part of VDSO this means that `clock_gettime` should be able to link statically as well. ### The problem However, [`_dl_non_dynamic_init`](https://code.woboq.org/userspace/glibc/csu/init-first.c.html#74) which has a run time path to malloc is called before [VDSO](https://code.woboq.org/userspace/glibc/csu/init-first.c.html#78) has been setup. Because malloc is now jemalloc, it will attempt to use `clock_gettime` which has not been setup properly. ### The possible solution I'm filing a bug in glibc tracker to apply this patch. This makes the sample program run, however there is another [`setup_vdso`](https://code.woboq.org/userspace/glibc/elf/setup-vdso.h.html#20) function which (without the patch applied) is called before `VDSO_SETUP` and I am unsure about the interactions between them. Can you please clarify/review? Thanks! ``` diff --git a/csu/init-first.c b/csu/init-first.c index 289373f9d8..330cc7d36c 100644 --- a/csu/init-first.c +++ b/csu/init-first.c @@ -68,16 +68,16 @@ _init (int argc, char **argv, char **envp) __libc_argv = argv; __environ = envp; +#ifdef VDSO_SETUP + VDSO_SETUP (); +#endif + #ifndef SHARED /* First the initialization which normally would be done by the dynamic linker. */ _dl_non_dynamic_init (); #endif -#ifdef VDSO_SETUP - VDSO_SETUP (); -#endif - __init_misc (argc, argv, envp); /* Initialize ctype data. */ ```
It will be fixed on 2.31 (1bdda52fe92fd01b424cd6fbb63e3df96a95015c). *** This bug has been marked as a duplicate of bug 24967 ***