1 /* Copyright (c) 2017 Yaakov Selkowitz <yselkowi@redhat.com> */
2 #include <sys/param.h>
3 #include <signal.h>
4 #include <stdlib.h>
5 #include <stdint.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include <stdio.h>
9
10 #if defined(__AMDGCN__) || defined(__nvptx__)
11 /* Global constructors not supported on this target, yet. */
12 uintptr_t __stack_chk_guard = 0x00000aff; /* 0, 0, '\n', 255 */
13
14 #else
15 uintptr_t __stack_chk_guard = 0;
16
17 int getentropy (void *, size_t) _ATTRIBUTE((__weak__));
18
19 void __stack_chk_init (void) __attribute__((__constructor__));
20
21 void
22 __attribute__((__constructor__))
__stack_chk_init(void)23 __stack_chk_init (void)
24 {
25 if (__stack_chk_guard != 0)
26 return;
27
28 if (getentropy) {
29 /* Use getentropy if available */
30 getentropy(&__stack_chk_guard, sizeof(__stack_chk_guard));
31 } else {
32 /* If getentropy is not available, use the "terminator canary". */
33 ((unsigned char *)&__stack_chk_guard)[0] = 0;
34 ((unsigned char *)&__stack_chk_guard)[1] = 0;
35 #if __SIZEOF_POINTER__ > 2
36 ((unsigned char *)&__stack_chk_guard)[2] = '\n';
37 ((unsigned char *)&__stack_chk_guard)[3] = 255;
38 #endif
39 }
40 }
41 #endif
42
43 _Noreturn void __stack_chk_fail (void);
44
45 #define STACK_CHK_MSG "*** stack smashing detected ***: terminated"
46
47 __typeof(__stack_chk_fail) __stack_chk_fail_weak;
48
49 _Noreturn void
__stack_chk_fail_weak(void)50 __stack_chk_fail_weak (void)
51 {
52 #ifdef TINY_STDIO
53 puts(STACK_CHK_MSG);
54 #else
55 static const char msg[] = STACK_CHK_MSG "\n";
56 write (2, msg, sizeof(msg)-1);
57 #endif
58 abort();
59 }
60 __weak_reference(__stack_chk_fail_weak, __stack_chk_fail);
61
62 #ifdef __ELF__
63
64 __typeof(__stack_chk_fail) __stack_chk_fail_local;
65
66 void
67 __attribute__((visibility ("hidden")))
__stack_chk_fail_local(void)68 __stack_chk_fail_local (void)
69 {
70 __stack_chk_fail();
71 }
72 #endif
73