diff options
author | Peter S. Mazinger <ps.m@gmx.net> | 2011-04-15 00:19:28 +0200 |
---|---|---|
committer | Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> | 2012-06-15 14:00:37 +0200 |
commit | 5c7e1909e1124c1cfc8251c158f3fb5301cdb1a5 (patch) | |
tree | 3d082af80da251f2c15c31080f78087345b66b05 /libc/sysdeps/linux | |
parent | c9a9baab4ff9ef22ee43e5e2b394b4d78980b7e0 (diff) |
ssp: rework, sync messages with the ones in glibc
Touch signals only if DODEBUG is enabled.
Make the signal selection dependent on DODEBUG, as last resort use SIGKILL.
Use internal functions with less arguments, some savings.
Fix a warning about unused argument.
Do not use openlog/closelog, while there remove their hidden versions.
Signed-off-by: Peter S. Mazinger <ps.m@gmx.net>
Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
Diffstat (limited to 'libc/sysdeps/linux')
-rw-r--r-- | libc/sysdeps/linux/common/ssp.c | 121 |
1 files changed, 66 insertions, 55 deletions
diff --git a/libc/sysdeps/linux/common/ssp.c b/libc/sysdeps/linux/common/ssp.c index 07513e7c4..8dcc3dc59 100644 --- a/libc/sysdeps/linux/common/ssp.c +++ b/libc/sysdeps/linux/common/ssp.c @@ -20,102 +20,113 @@ #error "file must not be compiled with stack protection enabled on it. Use -fno-stack-protector" #endif +#include <string.h> +#include <unistd.h> +#include <signal.h> +#ifdef __UCLIBC_HAS_SYSLOG__ +#include <sys/syslog.h> +#endif + #ifdef __PROPOLICE_BLOCK_SEGV__ # define SSP_SIGTYPE SIGSEGV #else # define SSP_SIGTYPE SIGABRT #endif -#include <string.h> -#include <unistd.h> -#include <signal.h> -#if defined __UCLIBC_HAS_SYSLOG__ -#include <sys/syslog.h> +static void do_write(const char *msg) +{ + /* could use inlined syscall here to be sure ... */ + return (void) write(STDERR_FILENO, msg, strlen(msg)); +} +static void __cold do_msg(const char *msg1, const char *msg2, const char *msg3) +{ + do_write(msg1); + do_write(msg2); + do_write(msg3); + do_write("\n"); +#ifdef __UCLIBC_HAS_SYSLOG__ + syslog(LOG_INFO, "%s%s%s()", msg1, msg2, msg3); #endif +} - -static void block_signals(void) +static void __cold attribute_noreturn +#ifdef __UCLIBC_HAS_SSP_COMPAT__ +ssp_handler(char func[]) +#else +ssp_handler(void) +#endif { + pid_t pid; + static const char msg_ssd[] = "*** stack smashing detected ***: "; + static const char msg_terminated[] = " terminated"; +#ifdef __UCLIBC_HAS_SSP_COMPAT__ + static const char msg_ssa[] = ": stack smashing attack in function "; +#endif + +#ifdef __DODEBUG__ struct sigaction sa; sigset_t mask; __sigfillset(&mask); __sigdelset(&mask, SSP_SIGTYPE); /* Block all signal handlers */ sigprocmask(SIG_BLOCK, &mask, NULL); /* except SSP_SIGTYPE */ +#endif + +#ifdef __UCLIBC_HAS_SSP_COMPAT__ + if (func != NULL) + do_msg(__uclibc_progname, msg_ssa, func); + else +#endif + do_msg(msg_ssd, __uclibc_progname, msg_terminated); + pid = getpid(); +#ifdef __DODEBUG__ /* Make the default handler associated with the signal handler */ memset(&sa, 0, sizeof(sa)); __sigfillset(&sa.sa_mask); /* Block all signals */ if (SIG_DFL) /* if it's constant zero, it's already done */ sa.sa_handler = SIG_DFL; - sigaction(SSP_SIGTYPE, &sa, NULL); -} - -static void __cold 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); -#if defined __UCLIBC_HAS_SYSLOG__ - openlog("ssp", LOG_CONS | LOG_PID, LOG_USER); - syslog(LOG_INFO, "%s%s%s()", msg1, msg2, msg3); - closelog(); + if (sigaction(SSP_SIGTYPE, &sa, NULL) == 0) + (void)kill(pid, SSP_SIGTYPE); #endif -} - -static attribute_noreturn void terminate(void) -{ - (void) kill(getpid(), SSP_SIGTYPE); - _exit(127); + (void)kill(pid, SIGKILL); + /* The loop is added only to keep gcc happy. */ + while(1) + _exit(127); } #ifdef __UCLIBC_HAS_SSP_COMPAT__ -void __stack_smash_handler(char func[], int damaged __attribute__ ((unused))) attribute_noreturn __cold; -void __stack_smash_handler(char func[], int damaged) +void __stack_smash_handler(char func[], int damaged) attribute_noreturn __cold; +void __stack_smash_handler(char func[], int damaged attribute_unused) { - static const char message[] = ": stack smashing attack in function "; - - block_signals(); - - ssp_write(STDERR_FILENO, __uclibc_progname, message, func); - - /* The loop is added only to keep gcc happy. */ - while(1) - terminate(); + ssp_handler(func); } -#endif -#ifdef __UCLIBC_HAS_SSP__ void __stack_chk_fail(void) { - static const char msg1[] = "stack smashing detected: "; - static const char msg3[] = " terminated"; - - block_signals(); - - ssp_write(STDERR_FILENO, msg1, __uclibc_progname, msg3); - - /* The loop is added only to keep gcc happy. */ - while(1) - terminate(); + ssp_handler(NULL); } +#else +strong_alias(ssp_handler,__stack_chk_fail) #endif #ifdef __UCLIBC_HAS_FORTIFY__ +/* should be redone when activated to use common code above. + * for now, it works without debugging support */ void __chk_fail(void) { - static const char msg1[] = "buffer overflow detected: "; - static const char msg3[] = " terminated"; - - block_signals(); + static const char msg_fail[] = "*** buffer overflow detected ***: "; + static const char msg_terminated[] = " terminated"; + pid_t pid; - ssp_write(STDERR_FILENO, msg1, __uclibc_progname, msg3); + do_msg(msg_fail, __uclibc_progname, msg_terminated); + pid = getpid(); + (void)kill(pid, SIGKILL); /* The loop is added only to keep gcc happy. */ while(1) - terminate(); + _exit(127); } libc_hidden_def(__chk_fail) #endif |