Skip to content

Commit 155cc03

Browse files
kateinoigakukunjohn-sharratt
authored andcommitted
Add -fstack-protector support to wasi-libc (WebAssembly#351)
Inlcude `__stack_chk_fail.c` and initialize `__stack_chk_guard` in ctor. ``` $ cat main.c char input[] = "0123456789012345"; int main(void) { char buf[8]; for (char *sp = input, *dp = buf; *sp != '\0'; sp++, dp++) { *dp = *sp; } return 0; } $ clang main.c -fstack-protector $ wasmtime ./a.out Error: failed to run main module `./a.out` Caused by: 0: failed to invoke command default 1: wasm trap: wasm `unreachable` instruction executed wasm backtrace: 0: 0x258 - <unknown>!__stack_chk_fail 1: 0x21e - <unknown>!__original_main 2: 0xca - <unknown>!_start ```
1 parent a829eba commit 155cc03

File tree

2 files changed

+28
-0
lines changed

2 files changed

+28
-0
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ LIBC_TOP_HALF_MUSL_SOURCES = \
146146
fcntl/creat.c \
147147
dirent/alphasort.c \
148148
dirent/versionsort.c \
149+
env/__stack_chk_fail.c \
149150
env/clearenv.c \
150151
env/getenv.c \
151152
env/putenv.c \

libc-top-half/musl/src/env/__stack_chk_fail.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
#include <string.h>
22
#include <stdint.h>
3+
#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT)
34
#include "pthread_impl.h"
5+
#else
6+
// In non-_REENTRANT, include it for `a_crash`
7+
# include "atomic.h"
8+
#endif
49

510
uintptr_t __stack_chk_guard;
611

@@ -9,7 +14,18 @@ void __init_ssp(void *entropy)
914
if (entropy) memcpy(&__stack_chk_guard, entropy, sizeof(uintptr_t));
1015
else __stack_chk_guard = (uintptr_t)&__stack_chk_guard * 1103515245;
1116

17+
#if UINTPTR_MAX >= 0xffffffffffffffff
18+
/* Sacrifice 8 bits of entropy on 64bit to prevent leaking/
19+
* overwriting the canary via string-manipulation functions.
20+
* The NULL byte is on the second byte so that off-by-ones can
21+
* still be detected. Endianness is taken care of
22+
* automatically. */
23+
((char *)&__stack_chk_guard)[1] = 0;
24+
#endif
25+
26+
#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT)
1227
__pthread_self()->canary = __stack_chk_guard;
28+
#endif
1329
}
1430

1531
void __stack_chk_fail(void)
@@ -20,3 +36,14 @@ void __stack_chk_fail(void)
2036
hidden void __stack_chk_fail_local(void);
2137

2238
weak_alias(__stack_chk_fail, __stack_chk_fail_local);
39+
40+
#ifndef __wasilibc_unmodified_upstream
41+
# include <wasi/api.h>
42+
43+
__attribute__((constructor(60)))
44+
static void __wasilibc_init_ssp(void) {
45+
uintptr_t entropy;
46+
int r = __wasi_random_get((uint8_t *)&entropy, sizeof(uintptr_t));
47+
__init_ssp(r ? NULL : &entropy);
48+
}
49+
#endif

0 commit comments

Comments
 (0)