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