master
1#include <string.h>
2#include <stdint.h>
3#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT)
4#include "pthread_impl.h"
5#else
6// In non-_REENTRANT, include it for `a_crash`
7# include "atomic.h"
8#endif
9
10uintptr_t __stack_chk_guard;
11
12void __init_ssp(void *entropy)
13{
14 if (entropy) memcpy(&__stack_chk_guard, entropy, sizeof(uintptr_t));
15 else __stack_chk_guard = (uintptr_t)&__stack_chk_guard * 1103515245;
16
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)
27 __pthread_self()->canary = __stack_chk_guard;
28#endif
29}
30
31void __stack_chk_fail(void)
32{
33 a_crash();
34}
35
36hidden void __stack_chk_fail_local(void);
37
38weak_alias(__stack_chk_fail, __stack_chk_fail_local);
39
40#ifndef __wasilibc_unmodified_upstream
41#ifdef __wasilibc_use_wasip2
42# include <wasi/libc.h>
43#else
44# include <wasi/api.h>
45#endif
46
47__attribute__((constructor(60)))
48static void __wasilibc_init_ssp(void) {
49 uintptr_t entropy;
50#ifdef __wasilibc_use_wasip2
51 int len = sizeof(uintptr_t);
52
53 int r = __wasilibc_random(&entropy, len);
54#else
55 int r = __wasi_random_get((uint8_t *)&entropy, sizeof(uintptr_t));
56#endif
57 __init_ssp(r ? NULL : &entropy);
58}
59#endif