Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 94325 | Differences between
and this patch

Collapse All | Expand All

(-)debug/stack_chk_fail.c.ORIG (-3 / +248 lines)
Lines 16-37 Link Here
16
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
16
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17
   02111-1307 USA.  */
17
   02111-1307 USA.  */
18
18
19
#if defined __SSP__ || defined __SSP_ALL__
20
21
/* An SSP failure handler that:
22
 * 1) does not use any function calls - which would
23
 *    otherwise lead to nested calls to stack_chk_fail()
24
 * 2) uses no functions from the rest of libc, which
25
 *    can lead to build problems pulling in copies of
26
 *    swathes of libc into the other libraries.
27
 * This handler would not be valid on architectures for
28
 * which a pointer is not either a 32-bit or 64-bit
29
 * integer.  It's definitely ok for i386, x86_64, and ppc.
30
 */
31
32
#if defined __linux__
33
34
/* When including headers, define out the function names used
35
 * via syscalls, since the syscall macros require that the functions
36
 * they declare have the predefined names.  This prevents duplicate
37
 * declaration issues, which are warnings on gcc-3 but have become
38
 * errors on gcc-4.
39
 */
40
#define exit lcexit
41
#include <stdlib.h>
42
#undef exit
43
#define write lcwrite
44
#define getpid lcgetpid
45
#define close lcclose
46
#include <unistd.h>
47
#undef write
48
#undef getpid
49
#undef close
50
#define kill lckill
51
#include <signal.h>
52
#undef kill
53
#include <linux/unistd.h>
54
#include <sys/types.h>
55
56
57
#ifndef __dietlibc__
58
59
#include <alloca.h>
60
61
/* from sysdeps */
62
#include <socketcall.h>
63
64
/* for the stuff in bits/socket.h */
65
#include <sys/socket.h>
66
67
#include <sys/un.h>
68
69
#endif
70
71
/* Re-configure errno to a local one */
72
#ifdef errno
73
#undef errno
74
#endif
75
#define errno __stack_chk_fail_errno
76
static unsigned long int __stack_chk_fail_errno;
77
78
static ssize_t write(int fd, const void *buf, size_t count) __attribute__ ((always_inline));
79
static _syscall3(ssize_t,write, int,fd, const void *,buf, size_t,count);
80
81
static void exit(int status) __attribute__ ((always_inline));
82
static _syscall1(void,exit, int,status);
83
84
static int kill(pid_t pid, int sig) __attribute__ ((always_inline));
85
static _syscall2(int,kill, pid_t,pid, int,sig);
86
87
static pid_t getpid(void) __attribute__ ((always_inline));
88
static _syscall0(pid_t,getpid);
89
90
#ifndef __dietlibc__
91
92
static int close(int fd) __attribute__ ((always_inline));
93
static _syscall1(int,close, int,fd);
94
95
96
/* socketcall is present on most arches (including x86, arm (some), ppc, ppc64, mips, mips64, sparc, sparc64)
97
 * x86_86 and some arm do not have it, but does have socket and connect syscalls
98
 * Assume this when socketcall is not available.
99
 */
100
#ifdef __NR_socketcall
101
102
static long socketcall(int call, unsigned long *args) __attribute__ ((always_inline));
103
static _syscall2(long,socketcall, int,call, unsigned long *,args);
104
105
#define DO_SOCKET(result,domain,type,protocol) \
106
	socketargs[0] = domain; \
107
	socketargs[1] = type; \
108
	socketargs[2] = protocol; \
109
	socketargs[3] = 0; \
110
	result = socketcall(SOCKOP_socket, socketargs)
111
112
#define DO_CONNECT(result,sockfd,serv_addr,addrlen) \
113
	socketargs[0] = sockfd; \
114
	socketargs[1] = (unsigned long int)serv_addr; \
115
	socketargs[2] = addrlen; \
116
	socketargs[3] = 0; \
117
	result = socketcall(SOCKOP_connect, socketargs)
118
119
#else
120
121
#ifndef __NR_local_inline_socket
122
#define __NR_local_inline_socket __NR_socket
123
#endif
124
125
#ifndef __NR_local_inline_connect
126
#define __NR_local_inline_connect __NR_connect
127
#endif
128
129
static int local_inline_socket(int domain, int type, int protocol) __attribute__ ((always_inline)) ;
130
static _syscall3(int,local_inline_socket, int,domain, int,type, int,protocol);
131
132
#define DO_SOCKET(result,domain,type,protocol) \
133
	result = local_inline_socket(domain,type,protocol)
134
135
static int local_inline_connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen) __attribute__ ((always_inline)) ;
136
static _syscall3(int,local_inline_connect, int,sockfd, const struct sockaddr *,serv_addr, socklen_t,addrlen);
137
138
#define DO_CONNECT(result,sockfd,serv_addr,addrlen) \
139
	result = local_inline_connect(sockfd,(struct sockaddr *)serv_addr, addrlen)
140
141
#endif
142
143
#ifndef _PATH_LOG
144
#define _PATH_LOG "/dev/log"
145
#endif
146
147
const char path_log[]=_PATH_LOG;
148
149
extern char *__progname;
150
151
#else
152
153
static char *__progname = "<dietapp>";
154
155
#endif
156
157
#else
158
/* not building on linux */
159
160
#error "Gentoo SSP support: glibc can only be built with SSP on Linux"
161
162
#endif
163
164
#else
165
/* not SSP */
166
167
#warning "Gentoo SSP support: building standard upstream handler, glibc itself is not protected"
168
19
#include <stdio.h>
169
#include <stdio.h>
20
#include <stdlib.h>
170
#include <stdlib.h>
21
171
22
172
23
extern char **__libc_argv attribute_hidden;
173
extern char **__libc_argv attribute_hidden;
24
174
175
#endif
176
/* endif SSP */
177
178
#if defined ENABLE_OLD_SSP_COMPAT
25
void
179
void
26
__attribute__ ((noreturn))
180
__attribute__ ((noreturn))
181
__attribute__ ((alias("__stack_smash_handler")))
27
__stack_chk_fail (void)
182
__stack_chk_fail (void)
28
{
183
{
184
#else /* defined ENABLE_OLD_SSP_COMPAT */
185
void
186
__attribute__ ((noreturn))
187
__stack_chk_fail (void)
188
{
189
#endif /* defined ENABLE_OLD_SSP_COMPAT */
190
191
#if defined __SSP__ || defined __SSP_ALL__
192
193
	#define MESSAGE_BUFSIZ 512
194
	pid_t pid;
195
	int plen, i;
196
	char message[MESSAGE_BUFSIZ];
197
	const char msg_prefix[]="*** stack smashing detected ***: ";
198
	const char msg_suffix[]=" terminated\n";
199
	const char msg_unknown[]="<unknown>";
200
#ifndef __dietlibc__
201
	int log_socket, connect_result;
202
	struct sockaddr_un sock;
203
#ifdef __NR_socketcall
204
	unsigned long int *socketargs=(unsigned long int *)alloca(sizeof(unsigned long int)*4);
205
#endif
206
#endif
207
208
	/* build message */
209
#define strconcat(str) \
210
	i=0; while ((str[i] != '\0') && ((i+plen)<(MESSAGE_BUFSIZ-1))) {\
211
		message[plen+i]=str[i];\
212
		i++;\
213
	}\
214
	plen+=i;
215
	plen=0;
216
	strconcat(msg_prefix);
217
	if (__progname != (char *)0) {
218
		strconcat(__progname);
219
	} else {
220
		strconcat(msg_unknown);
221
	}
222
	strconcat(msg_suffix);
223
	message[plen++]='\0';
224
225
	/* Write out error message to STDERR */
226
	write(STDERR_FILENO, message, plen);
227
228
#ifndef __dietlibc__
229
	/* Log to syslog; socket write to /dev/log */
230
231
	/* Build socket address */
232
	sock.sun_family = AF_UNIX;
233
	i=0; while ((path_log[i] != '\0') && (i<(sizeof(sock.sun_path)-1))) {
234
		sock.sun_path[i]=path_log[i];
235
		i++;
236
	}
237
	sock.sun_path[i]='\0';
238
239
	/* Try SOCK_DGRAM connection to syslog */
240
	connect_result=-1;
241
	DO_SOCKET(log_socket,AF_UNIX,SOCK_DGRAM,0);
242
	if (log_socket != -1) {
243
		DO_CONNECT(connect_result,log_socket,(&sock),(sizeof(sock)));
244
	}
245
	if (connect_result == -1) {
246
		if (log_socket != -1) {
247
			close(log_socket);
248
		}
249
		/* Try SOCK_STREAM connection to syslog */
250
		DO_SOCKET(log_socket,AF_UNIX,SOCK_STREAM,0);
251
		if (log_socket != -1) {
252
			DO_CONNECT(connect_result,log_socket,(&sock),(sizeof(sock)));
253
		}
254
	}
255
	/* If a successful connection was made, log the message */
256
	if (connect_result != -1) {
257
		write(log_socket,message,plen);
258
	}
259
	if (log_socket != -1) {
260
		close(log_socket);
261
	}
262
#endif
263
264
	/* Suicide - note; sigactions can't be added to SIGKILL, nor can it be masked */
265
	pid=getpid();
266
	kill(pid,SIGKILL);
267
268
	/* In case the kill didn't work, exit anyway
269
	 * The loop prevents gcc thinking this routine returns
270
	 */
271
	while (1) exit(EXIT_FAILURE);
272
273
#else
274
29
  /* The loop is added only to keep gcc happy.  */
275
  /* The loop is added only to keep gcc happy.  */
30
  while (1)
276
  while (1)
31
    __libc_message (1, "*** stack smashing detected ***: %s terminated\n",
277
    __libc_message (1, "*** stack smashing detected ***: %s terminated\n",
32
		    __libc_argv[0] ?: "<unknown>");
278
		    __libc_argv[0] ?: "<unknown>");
33
}
34
279
35
#ifdef ENABLE_OLD_SSP_COMPAT
36
strong_alias (__stack_chk_fail, __stack_smash_handler)
37
#endif
280
#endif
281
}
282

Return to bug 94325