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