diff options
Diffstat (limited to 'libc/sysdeps/linux/common')
-rw-r--r-- | libc/sysdeps/linux/common/ssp-local.c | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/libc/sysdeps/linux/common/ssp-local.c b/libc/sysdeps/linux/common/ssp-local.c new file mode 100644 index 000000000..7791a0104 --- /dev/null +++ b/libc/sysdeps/linux/common/ssp-local.c @@ -0,0 +1,103 @@ +/* + * Distributed under the terms of the GNU Lesser General Public License + * $Header: $ + * + * This is a modified version of Hiroaki Etoh's stack smashing routines + * implemented for glibc. + * + * The following people have contributed input to this code. + * Ned Ludd - <solar[@]gentoo.org> + * Alexander Gabert - <pappy[@]gentoo.org> + * The PaX Team - <pageexec[@]freemail.hu> + * Peter S. Mazinger - <ps.m[@]gmx.net> + * Yoann Vandoorselaere - <yoann[@]prelude-ids.org> + * Robert Connolly - <robert[@]linuxfromscratch.org> + * Cory Visi <cory[@]visi.name> + * Mike Frysinger <vapier[@]gentoo.org> + */ + +#include <string.h> +#include <unistd.h> +#include <sys/syslog.h> + +#include <ssp-internal.h> + +static __always_inline void block_signals(void) +{ + struct sigaction sa; + sigset_t mask; + + sigfillset(&mask); + + sigdelset(&mask, SSP_SIGTYPE); /* Block all signal handlers */ + SIGPROCMASK(SIG_BLOCK, &mask, NULL); /* except SSP_SIGTYPE */ + + /* Make the default handler associated with the signal handler */ + memset(&sa, 0, sizeof(struct sigaction)); + sigfillset(&sa.sa_mask); /* Block all signals */ + sa.sa_flags = 0; + sa.sa_handler = SIG_DFL; + SIGACTION(SSP_SIGTYPE, &sa, NULL); +} + +static __always_inline void ssp_write(int fd, const char *msg1, const char *msg2, const char *msg3) +{ + WRITE(fd, msg1, strlen(msg1)); + WRITE(fd, msg2, strlen(msg2)); + WRITE(fd, msg3, strlen(msg3)); + WRITE(fd, "()\n", 3); + openlog("ssp", LOG_CONS | LOG_PID, LOG_USER); + syslog(LOG_INFO, "%s%s%s()", msg1, msg2, msg3); + closelog(); +} + +static __always_inline void terminate(void) +{ + (void) KILL(GETPID(), SSP_SIGTYPE); + EXIT(127); +} + +void __attribute__ ((noreturn)) __stack_smash_handler(char func[], int damaged __attribute__ ((unused))); +void __attribute__ ((noreturn)) __stack_smash_handler(char func[], int damaged) +{ + extern char *__progname; + static const char message[] = ": stack smashing attack in function "; + + block_signals(); + + ssp_write(STDERR_FILENO, __progname, message, func); + + /* The loop is added only to keep gcc happy. */ + while(1) + terminate(); +} + +void __attribute__ ((noreturn)) __stack_chk_fail(void) +{ + extern char *__progname; + static const char msg1[] = "stack smashing detected: "; + static const char msg3[] = " terminated"; + + block_signals(); + + ssp_write(STDERR_FILENO, msg1, __progname, msg3); + + /* The loop is added only to keep gcc happy. */ + while(1) + terminate(); +} + +void __attribute__ ((noreturn)) __chk_fail(void) +{ + extern char *__progname; + static const char msg1[] = "buffer overflow detected: "; + static const char msg3[] = " terminated"; + + block_signals(); + + ssp_write(STDERR_FILENO, msg1, __progname, msg3); + + /* The loop is added only to keep gcc happy. */ + while(1) + terminate(); +} |