2 * Distributed under the terms of the GNU General Public License v2
3 * $Header: /var/cvs/uClibc/libc/sysdeps/linux/common/ssp.c,v 1.6 2005/01/11 17:01:53 vapier Exp $
5 * This is a modified version of Hiroaki Etoh's stack smashing routines
6 * implemented for glibc.
8 * The following people have contributed input to this code.
9 * Ned Ludd - <solar[@]gentoo.org>
10 * Alexander Gabert - <pappy[@]gentoo.org>
11 * The PaX Team - <pageexec[@]freemail.hu>
12 * Peter S. Mazinger - <ps.m[@]gmx.net>
13 * Yoann Vandoorselaere - <yoann[@]prelude-ids.org>
14 * Robert Connolly - <robert[@]linuxfromscratch.org>
15 * Cory Visi <cory@visi.name>
28 #include <sys/types.h>
30 #include <sys/syslog.h>
32 #ifdef __SSP_USE_ERANDOM__
33 #include <sys/sysctl.h>
36 #ifdef __PROPOLICE_BLOCK_SEGV__
37 #define SSP_SIGTYPE SIGSEGV
38 #elif __PROPOLICE_BLOCK_KILL__
39 #define SSP_SIGTYPE SIGKILL
41 #define SSP_SIGTYPE SIGABRT
44 unsigned long __guard = 0UL;
46 void __guard_setup(void) __attribute__ ((constructor));
47 void __guard_setup(void)
55 /* Start with the "terminator canary". */
56 __guard = 0xFF0A0D00UL;
58 #ifndef __SSP_QUICK_CANARY__
59 #ifdef __SSP_USE_ERANDOM__
61 /* Random is another depth in Linux, hence an array of 3. */
64 mib[2] = RANDOM_ERANDOM;
66 size = sizeof(unsigned long);
67 if (__sysctl(mib, 3, &__guard, &size, NULL, 0) != (-1))
72 * Attempt to open kernel pseudo random device if one exists before
73 * opening urandom to avoid system entropy depletion.
78 #ifdef __SSP_USE_ERANDOM__
79 if ((fd = __libc_open("/dev/erandom", O_RDONLY)) == (-1))
81 fd = __libc_open("/dev/urandom", O_RDONLY);
83 size = __libc_read(fd, (char *) &__guard, sizeof(__guard));
85 if (size == sizeof(__guard))
91 /* Everything failed? Or we are using a weakened model of the
92 * terminator canary */
94 gettimeofday(&tv, NULL);
95 __guard ^= tv.tv_usec ^ tv.tv_sec;
98 void __stack_smash_handler(char func[], int damaged __attribute__ ((unused)));
99 void __stack_smash_handler(char func[], int damaged)
101 extern char *__progname;
102 const char message[] = ": stack smashing attack in function ";
108 sigdelset(&mask, SSP_SIGTYPE); /* Block all signal handlers */
109 sigprocmask(SIG_BLOCK, &mask, NULL); /* except SSP_SIGTYPE */
111 /* Print error message to stderr and syslog */
112 fprintf(stderr, "%s%s%s()\n", __progname, message, func);
113 syslog(LOG_INFO, "%s%s%s()", __progname, message, func);
115 /* Make the default handler associated with the signal handler */
116 memset(&sa, 0, sizeof(struct sigaction));
117 sigfillset(&sa.sa_mask); /* Block all signals */
119 sa.sa_handler = SIG_DFL;
120 sigaction(SSP_SIGTYPE, &sa, NULL);
121 (void) kill(getpid(), SSP_SIGTYPE);