]>
Commit | Line | Data |
---|---|---|
cd1a2927 MT |
1 | Submitted By: Robert Connolly <cendres at videotron dot ca> (ashes) |
2 | Date: 2004-04-24 | |
3 | Initial Package Version: 2.3.3 | |
4 | Origin: http://www.research.ibm.com/trl/projects/security/ssp/ | |
5 | http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/sys/stack_protector.c | |
6 | Description: Smashing Stack Protector - This patch adds guard functions to | |
7 | Glibc. | |
8 | ||
9 | This patch depends on erandom sysctl from: | |
10 | http://frandom.sourceforge.net/ | |
11 | http://www.linuxfromscratch.org/hints/downloads/files/entropy.txt | |
12 | ||
13 | Also see: | |
14 | http://www.research.ibm.com/trl/projects/security/ssp/ | |
15 | http://www.linuxfromscratch.org/hlfs/ | |
16 | http://www.linuxfromscratch.org/hints/downloads/files/ssp.txt | |
17 | ||
18 | diff -Naur glibc-2.3-20040418.orig/sysdeps/generic/libc-start.c glibc-2.3-20040418.ssp-frandom/sysdeps/generic/libc-start.c | |
19 | --- glibc-2.3-20040418.orig/sysdeps/generic/libc-start.c 2004-03-31 01:46:43.000000000 +0000 | |
20 | +++ glibc-2.3-20040418.ssp-frandom/sysdeps/generic/libc-start.c 2004-04-25 07:07:34.000000000 +0000 | |
21 | @@ -188,6 +188,8 @@ | |
22 | GLRO(dl_debug_printf) ("\ntransferring control: %s\n\n", argv[0]); | |
23 | #endif | |
24 | ||
25 | + __guard_setup (); | |
26 | + | |
27 | #ifdef HAVE_CLEANUP_JMP_BUF | |
28 | /* Memory for the cancellation buffer. */ | |
29 | struct pthread_unwind_buf unwind_buf; | |
30 | diff -Naur glibc-2.3-20040418.orig/sysdeps/unix/sysv/linux/Dist glibc-2.3-20040418.ssp-frandom/sysdeps/unix/sysv/linux/Dist | |
31 | --- glibc-2.3-20040418.orig/sysdeps/unix/sysv/linux/Dist 2003-09-24 05:04:29.000000000 +0000 | |
32 | +++ glibc-2.3-20040418.ssp-frandom/sysdeps/unix/sysv/linux/Dist 2004-04-25 07:09:46.000000000 +0000 | |
33 | @@ -1,3 +1,4 @@ | |
34 | +stack_protector.c | |
35 | bits/initspin.h | |
36 | cmsg_nxthdr.c | |
37 | dl-brk.c | |
38 | diff -Naur glibc-2.3-20040418.orig/sysdeps/unix/sysv/linux/Makefile glibc-2.3-20040418.ssp-frandom/sysdeps/unix/sysv/linux/Makefile | |
39 | --- glibc-2.3-20040418.orig/sysdeps/unix/sysv/linux/Makefile 2004-04-03 07:45:26.000000000 +0000 | |
40 | +++ glibc-2.3-20040418.ssp-frandom/sysdeps/unix/sysv/linux/Makefile 2004-04-25 07:10:02.000000000 +0000 | |
41 | @@ -1,5 +1,5 @@ | |
42 | ifeq ($(subdir),csu) | |
43 | -sysdep_routines += errno-loc | |
44 | +sysdep_routines += errno-loc stack_protector | |
45 | endif | |
46 | ||
47 | ifeq ($(subdir),assert) | |
48 | diff -Naur glibc-2.3-20040418.orig/sysdeps/unix/sysv/linux/Versions glibc-2.3-20040418.ssp-frandom/sysdeps/unix/sysv/linux/Versions | |
49 | --- glibc-2.3-20040418.orig/sysdeps/unix/sysv/linux/Versions 2004-03-19 00:13:55.000000000 +0000 | |
50 | +++ glibc-2.3-20040418.ssp-frandom/sysdeps/unix/sysv/linux/Versions 2004-04-25 07:08:58.000000000 +0000 | |
51 | @@ -108,6 +108,7 @@ | |
52 | GLIBC_2.3.2 { | |
53 | # New kernel interfaces. | |
54 | epoll_create; epoll_ctl; epoll_wait; | |
55 | + __guard; __guard_setup; __stack_smash_handler; | |
56 | } | |
57 | GLIBC_2.3.3 { | |
58 | gnu_dev_major; gnu_dev_minor; gnu_dev_makedev; | |
59 | diff -Naur glibc-2.3-20040418.orig/sysdeps/unix/sysv/linux/stack_protector.c glibc-2.3-20040418.ssp-frandom/sysdeps/unix/sysv/linux/stack_protector.c | |
60 | --- glibc-2.3-20040418.orig/sysdeps/unix/sysv/linux/stack_protector.c 1970-01-01 00:00:00.000000000 +0000 | |
61 | +++ glibc-2.3-20040418.ssp-frandom/sysdeps/unix/sysv/linux/stack_protector.c 2004-04-25 07:24:27.000000000 +0000 | |
62 | @@ -0,0 +1,160 @@ | |
63 | +/* $hlfs: ssp.c,v 1.1 2004/04/24 00:00:00 robert Exp $ */ | |
64 | + | |
65 | +/* Most of this code was copied from the gcc patch, libgcc2.c hunk, from | |
66 | + * http://www.trl.ibm.com/projects/security/ssp/ | |
67 | + * And therefore this code is part of gcc. | |
68 | + */ | |
69 | + | |
70 | +/* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, | |
71 | + 2000, 2001, 2002 Free Software Foundation, Inc. | |
72 | + | |
73 | +This file is part of GCC. | |
74 | + | |
75 | +GCC is free software; you can redistribute it and/or modify it under | |
76 | +the terms of the GNU General Public License as published by the Free | |
77 | +Software Foundation; either version 2, or (at your option) any later | |
78 | +version. | |
79 | + | |
80 | +In addition to the permissions in the GNU General Public License, the | |
81 | +Free Software Foundation gives you unlimited permission to link the | |
82 | +compiled version of this file into combinations with other programs, | |
83 | +and to distribute those combinations without any restriction coming | |
84 | +from the use of this file. (The General Public License restrictions | |
85 | +do apply in other respects; for example, they cover modification of | |
86 | +the file, and distribution when not linked into a combine | |
87 | +executable.) | |
88 | + | |
89 | +GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
90 | +WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
91 | +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
92 | +for more details. | |
93 | + | |
94 | +You should have received a copy of the GNU General Public License | |
95 | +along with GCC; see the file COPYING. If not, write to the Free | |
96 | +Software Foundation, 59 Temple Place - Suite 330, Boston, MA | |
97 | +02111-1307, USA. */ | |
98 | + | |
99 | +/* Some portions of this code were copied from | |
100 | + * http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/sys/stack_protector.c | |
101 | + * And hence a dual license. | |
102 | + */ | |
103 | + | |
104 | +/* | |
105 | + * Copyright (c) 2002 Hiroaki Etoh, Federico G. Schwindt, and Miodrag Vallat. | |
106 | + * All rights reserved. | |
107 | + * | |
108 | + * Redistribution and use in source and binary forms, with or without | |
109 | + * modification, are permitted provided that the following conditions | |
110 | + * are met: | |
111 | + * 1. Redistributions of source code must retain the above copyright | |
112 | + * notice, this list of conditions and the following disclaimer. | |
113 | + * 2. Redistributions in binary form must reproduce the above copyright | |
114 | + * notice, this list of conditions and the following disclaimer in the | |
115 | + * documentation and/or other materials provided with the distribution. | |
116 | + * | |
117 | + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR | |
118 | + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
119 | + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
120 | + * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, | |
121 | + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
122 | + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
123 | + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
124 | + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
125 | + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | |
126 | + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
127 | + * POSSIBILITY OF SUCH DAMAGE. | |
128 | + * | |
129 | + */ | |
130 | + | |
131 | +#include <stdio.h> | |
132 | +#include <string.h> | |
133 | +#include <fcntl.h> | |
134 | +#include <unistd.h> | |
135 | +#include <sys/sysctl.h> | |
136 | + | |
137 | +#include <signal.h> | |
138 | + | |
139 | +#include <sys/types.h> | |
140 | +#include <sys/socket.h> | |
141 | +#include <sys/un.h> | |
142 | + | |
143 | +#include <sys/syslog.h> | |
144 | +#ifndef _PATH_LOG | |
145 | +#define _PATH_LOG "/dev/log" | |
146 | +#endif | |
147 | + | |
148 | +long __guard[8] = {0, 0, 0, 0, 0, 0, 0, 0}; | |
149 | + | |
150 | +void __guard_setup (void) | |
151 | +{ | |
152 | + int i, mib[3]; | |
153 | + size_t len; | |
154 | + | |
155 | + if (__guard[0] != 0) | |
156 | + return; | |
157 | + | |
158 | + /* Random is another depth in Linux, hence an array of 3. */ | |
159 | + mib[0] = CTL_KERN; | |
160 | + mib[1] = KERN_RANDOM; | |
161 | + mib[2] = RANDOM_ERANDOM; | |
162 | + | |
163 | + len = 4; | |
164 | + for (i = 0; i < sizeof(__guard) / 4; i++) { | |
165 | + if (sysctl(mib, 3, (char *)&((int *)__guard)[i], | |
166 | + &len, NULL, 0) == -1) | |
167 | + break; | |
168 | + } | |
169 | + | |
170 | + if (i < sizeof(__guard) / 4) { | |
171 | + /* If sysctl was unsuccessful, use the "terminator canary". */ | |
172 | + ((char *)__guard)[0] = 0; ((char*)__guard)[1] = 0; | |
173 | + ((char *)__guard)[2] = '\n'; ((char *)__guard)[3] = 255; | |
174 | + } | |
175 | +} | |
176 | + | |
177 | +void __stack_smash_handler (char func[], int damaged) | |
178 | +{ | |
179 | + extern char * __progname; | |
180 | + const char message[] = ": stack smashing attack in function "; | |
181 | + int bufsz = 512, len; | |
182 | + char buf[bufsz]; | |
183 | + int LogFile; | |
184 | + struct sockaddr_un SyslogAddr; /* AF_UNIX address of local logger */ | |
185 | + | |
186 | + sigset_t mask; | |
187 | + sigfillset(&mask); | |
188 | + sigdelset(&mask, SIGABRT); /* Block all signal handlers */ | |
189 | + sigprocmask(SIG_BLOCK, &mask, NULL); /* except SIGABRT */ | |
190 | + | |
191 | + strcpy(buf, "<2>"); len=3; /* send LOG_CRIT */ | |
192 | + strncat(buf, __progname, bufsz-len-1); len = strlen(buf); | |
193 | + if (bufsz>len) {strncat(buf, message, bufsz-len-1); len = strlen(buf);} | |
194 | + if (bufsz>len) {strncat(buf, func, bufsz-len-1); len = strlen(buf);} | |
195 | + /* print error message */ | |
196 | + write (STDERR_FILENO, buf+3, len-3); | |
197 | + if ((LogFile = socket(AF_UNIX, SOCK_DGRAM, 0)) != -1) { | |
198 | + /* | |
199 | + * Send "found" message to the "/dev/log" path | |
200 | + */ | |
201 | + SyslogAddr.sun_family = AF_UNIX; | |
202 | + (void)strncpy(SyslogAddr.sun_path, _PATH_LOG, | |
203 | + sizeof(SyslogAddr.sun_path) - 1); | |
204 | + SyslogAddr.sun_path[sizeof(SyslogAddr.sun_path) - 1] = '\0'; | |
205 | + sendto(LogFile, buf, len, 0, (struct sockaddr *)&SyslogAddr, | |
206 | + sizeof(SyslogAddr)); | |
207 | + } | |
208 | + | |
209 | + /* Make sure the default handler is associated with SIGABRT */ | |
210 | + struct sigaction sa; | |
211 | + | |
212 | + memset(&sa, 0, sizeof(struct sigaction)); | |
213 | + sigfillset(&sa.sa_mask); /* Block all signals */ | |
214 | + sa.sa_flags = 0; | |
215 | + sa.sa_handler = SIG_DFL; | |
216 | + sigaction(SIGABRT, &sa, NULL); | |
217 | + | |
218 | + (void)kill(getpid(), SIGABRT); | |
219 | + | |
220 | + _exit(127); | |
221 | +} | |
222 | + |