diff options
author | Rich Felker <dalias@aerifal.cx> | 2018-10-17 22:20:01 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2018-10-17 22:20:01 -0400 |
commit | 4390383b32250a941ec616e8bff6f568a801b1c0 (patch) | |
tree | 2f9a928ddaf558a7b0ec81e38abb6f9c48578aba /src/env | |
parent | a4a3e4dbc086eb58e5cf6118480ef4825788e231 (diff) | |
download | musl-4390383b32250a941ec616e8bff6f568a801b1c0.zip musl-4390383b32250a941ec616e8bff6f568a801b1c0.tar.gz musl-4390383b32250a941ec616e8bff6f568a801b1c0.tar.bz2 |
impose barrier between thread pointer setup and use for static linking
this is the analog of commit 1c84c99913bf1cd47b866ed31e665848a0da84a2
for static linking. unlike with dynamic linking, we don't have
symbolic lookup to use as a barrier. use a dummy (target-agnostic)
degenerate inline asm fragment instead. this technique has precedent
in commit 05ac345f895098657cf44d419b5d572161ebaf43 where it's used for
explicit_bzero. if it proves problematic in any way, loading the
address of the stage 2 function from a pointer object whose address
leaks to kernelspace during thread pointer init could be used as an
even stronger barrier.
Diffstat (limited to 'src/env')
-rw-r--r-- | src/env/__libc_start_main.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/src/env/__libc_start_main.c b/src/env/__libc_start_main.c index 58da9e8..ba4d213 100644 --- a/src/env/__libc_start_main.c +++ b/src/env/__libc_start_main.c @@ -63,11 +63,24 @@ static void libc_start_init(void) weak_alias(libc_start_init, __libc_start_init); +static int libc_start_main_stage2(int (*)(int,char **,char **), int, char **); + int __libc_start_main(int (*main)(int,char **,char **), int argc, char **argv) { char **envp = argv+argc+1; __init_libc(envp, argv[0]); + + /* Barrier against hoisting application code or anything using ssp + * or thread pointer prior to its initialization above. */ + int (*stage2)(); + __asm__ ( "" : "=r"(stage2) : "r"(libc_start_main_stage2) : "memory" ); + return stage2(main, argc, argv); +} + +static int libc_start_main_stage2(int (*main)(int,char **,char **), int argc, char **argv) +{ + char **envp = argv+argc+1; __libc_start_init(); /* Pass control to the application */ |