Mercurial > hg > CbC > CbC_gcc
annotate libssp/ssp.c @ 158:494b0b89df80 default tip
...
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 25 May 2020 18:13:55 +0900 |
parents | 1830386684a0 |
children |
rev | line source |
---|---|
0 | 1 /* Stack protector support. |
145 | 2 Copyright (C) 2005-2020 Free Software Foundation, Inc. |
0 | 3 |
4 This file is part of GCC. | |
5 | |
6 GCC is free software; you can redistribute it and/or modify it under | |
7 the terms of the GNU General Public License as published by the Free | |
8 Software Foundation; either version 3, or (at your option) any later | |
9 version. | |
10 | |
11 In addition to the permissions in the GNU General Public License, the | |
12 Free Software Foundation gives you unlimited permission to link the | |
13 compiled version of this file into combinations with other programs, | |
14 and to distribute those combinations without any restriction coming | |
15 from the use of this file. (The General Public License restrictions | |
16 do apply in other respects; for example, they cover modification of | |
17 the file, and distribution when not linked into a combine | |
18 executable.) | |
19 | |
20 GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
21 WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
22 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
23 for more details. | |
24 | |
25 Under Section 7 of GPL version 3, you are granted additional | |
26 permissions described in the GCC Runtime Library Exception, version | |
27 3.1, as published by the Free Software Foundation. | |
28 | |
29 You should have received a copy of the GNU General Public License and | |
30 a copy of the GCC Runtime Library Exception along with this program; | |
31 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
32 <http://www.gnu.org/licenses/>. */ | |
33 | |
34 | |
35 #include "config.h" | |
36 #ifdef HAVE_ALLOCA_H | |
37 # include <alloca.h> | |
38 #endif | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
39 #ifdef HAVE_MALLOC_H |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
40 # include <malloc.h> |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
41 #endif |
0 | 42 #ifdef HAVE_STRING_H |
43 # include <string.h> | |
44 #endif | |
45 #ifdef HAVE_UNISTD_H | |
46 # include <unistd.h> | |
47 #endif | |
48 #ifdef HAVE_FCNTL_H | |
49 # include <fcntl.h> | |
50 #endif | |
51 #ifdef HAVE_PATHS_H | |
52 # include <paths.h> | |
53 #endif | |
54 #ifndef _PATH_TTY | |
55 /* Native win32 apps don't know about /dev/tty but can print directly | |
56 to the console using "CONOUT$" */ | |
57 #if defined (_WIN32) && !defined (__CYGWIN__) | |
111 | 58 #include <windows.h> |
59 #include <wincrypt.h> | |
0 | 60 # define _PATH_TTY "CONOUT$" |
61 #else | |
62 # define _PATH_TTY "/dev/tty" | |
63 #endif | |
64 #endif | |
65 #ifdef HAVE_SYSLOG_H | |
66 # include <syslog.h> | |
67 #endif | |
68 | |
69 void *__stack_chk_guard = 0; | |
70 | |
71 static void __attribute__ ((constructor)) | |
72 __guard_setup (void) | |
73 { | |
74 unsigned char *p; | |
75 | |
76 if (__stack_chk_guard != 0) | |
77 return; | |
78 | |
111 | 79 #if defined (_WIN32) && !defined (__CYGWIN__) |
80 HCRYPTPROV hprovider = 0; | |
81 if (CryptAcquireContext(&hprovider, NULL, NULL, PROV_RSA_FULL, | |
82 CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) | |
83 { | |
84 if (CryptGenRandom(hprovider, sizeof (__stack_chk_guard), | |
85 (BYTE *)&__stack_chk_guard) && __stack_chk_guard != 0) | |
86 { | |
87 CryptReleaseContext(hprovider, 0); | |
88 return; | |
89 } | |
90 CryptReleaseContext(hprovider, 0); | |
91 } | |
92 #else | |
93 int fd = open ("/dev/urandom", O_RDONLY); | |
0 | 94 if (fd != -1) |
95 { | |
96 ssize_t size = read (fd, &__stack_chk_guard, | |
97 sizeof (__stack_chk_guard)); | |
98 close (fd); | |
99 if (size == sizeof(__stack_chk_guard) && __stack_chk_guard != 0) | |
100 return; | |
101 } | |
102 | |
111 | 103 #endif |
0 | 104 /* If a random generator can't be used, the protector switches the guard |
105 to the "terminator canary". */ | |
106 p = (unsigned char *) &__stack_chk_guard; | |
107 p[sizeof(__stack_chk_guard)-1] = 255; | |
108 p[sizeof(__stack_chk_guard)-2] = '\n'; | |
109 p[0] = 0; | |
110 } | |
111 | |
112 static void | |
113 fail (const char *msg1, size_t msg1len, const char *msg3) | |
114 { | |
115 #ifdef __GNU_LIBRARY__ | |
116 extern char * __progname; | |
117 #else | |
118 static const char __progname[] = ""; | |
119 #endif | |
120 int fd; | |
121 | |
122 /* Print error message directly to the tty. This avoids Bad Things | |
123 happening if stderr is redirected. */ | |
124 fd = open (_PATH_TTY, O_WRONLY); | |
125 if (fd != -1) | |
126 { | |
127 static const char msg2[] = " terminated\n"; | |
128 size_t progname_len, len; | |
129 char *buf, *p; | |
130 | |
131 progname_len = strlen (__progname); | |
132 len = msg1len + progname_len + sizeof(msg2)-1 + 1; | |
133 p = buf = alloca (len); | |
134 | |
135 memcpy (p, msg1, msg1len); | |
136 p += msg1len; | |
137 memcpy (p, __progname, progname_len); | |
138 p += progname_len; | |
139 memcpy (p, msg2, sizeof(msg2)); | |
140 | |
141 while (len > 0) | |
142 { | |
143 ssize_t wrote = write (fd, buf, len); | |
144 if (wrote < 0) | |
145 break; | |
146 buf += wrote; | |
147 len -= wrote; | |
148 } | |
149 close (fd); | |
150 } | |
151 | |
152 #ifdef HAVE_SYSLOG_H | |
153 /* Only send the error to syslog if there was no tty available. */ | |
154 else | |
111 | 155 syslog (LOG_CRIT, "%s", msg3); |
0 | 156 #endif /* HAVE_SYSLOG_H */ |
157 | |
158 /* Try very hard to exit. Note that signals may be blocked preventing | |
159 the first two options from working. The use of volatile is here to | |
160 prevent optimizers from "knowing" that __builtin_trap is called first, | |
161 and that it doesn't return, and so "obviously" the rest of the code | |
162 is dead. */ | |
163 { | |
164 volatile int state; | |
165 for (state = 0; ; state++) | |
166 switch (state) | |
167 { | |
168 case 0: | |
169 __builtin_trap (); | |
170 break; | |
171 case 1: | |
172 *(volatile int *)-1L = 0; | |
173 break; | |
174 case 2: | |
175 _exit (127); | |
176 break; | |
177 } | |
178 } | |
179 } | |
180 | |
181 void | |
182 __stack_chk_fail (void) | |
183 { | |
184 const char *msg = "*** stack smashing detected ***: "; | |
185 fail (msg, strlen (msg), "stack smashing detected: terminated"); | |
186 } | |
187 | |
188 void | |
189 __chk_fail (void) | |
190 { | |
191 const char *msg = "*** buffer overflow detected ***: "; | |
192 fail (msg, strlen (msg), "buffer overflow detected: terminated"); | |
193 } | |
194 | |
195 #ifdef HAVE_HIDDEN_VISIBILITY | |
196 void | |
197 __attribute__((visibility ("hidden"))) | |
198 __stack_chk_fail_local (void) | |
199 { | |
200 __stack_chk_fail (); | |
201 } | |
202 #endif |