1 /* Copyright (c) 2017 Yaakov Selkowitz <yselkowi@redhat.com> */
2 #include <sys/cdefs.h>
3 #include <sys/param.h>
4 #include <signal.h>
5 #include <stdlib.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
20 __attribute__((__constructor__))
__stack_chk_init(void)21 __stack_chk_init (void)
22 {
23   if (__stack_chk_guard != 0)
24     return;
25 
26   if (getentropy) {
27     /* Use getentropy if available */
28     getentropy(&__stack_chk_guard, sizeof(__stack_chk_guard));
29   } else {
30     /* If getentropy is not available, use the "terminator canary". */
31     ((unsigned char *)&__stack_chk_guard)[0] = 0;
32     ((unsigned char *)&__stack_chk_guard)[1] = 0;
33 #if __SIZEOF_POINTER__ > 2
34     ((unsigned char *)&__stack_chk_guard)[2] = '\n';
35     ((unsigned char *)&__stack_chk_guard)[3] = 255;
36 #endif
37   }
38 }
39 #endif
40 
41 void __stack_chk_fail (void) __attribute__((__noreturn__));
42 
43 #define STACK_CHK_MSG "*** stack smashing detected ***: terminated"
44 
45 void
46 __attribute__((__noreturn__))
__stack_chk_fail_weak(void)47 __stack_chk_fail_weak (void)
48 {
49 #ifdef TINY_STDIO
50   puts(STACK_CHK_MSG);
51 #else
52   static const char msg[] = STACK_CHK_MSG "\n";
53   write (2, msg, sizeof(msg)-1);
54 #endif
55   raise (SIGABRT);
56   _exit (127);
57 }
58 __weak_reference(__stack_chk_fail_weak, __stack_chk_fail);
59 
60 #ifdef __ELF__
61 void
62 __attribute__((visibility ("hidden")))
__stack_chk_fail_local(void)63 __stack_chk_fail_local (void)
64 {
65 	__stack_chk_fail();
66 }
67 #endif
68