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 | |
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>
-rw-r--r-- | extra/Configs/Config.in | 4 | ||||
-rw-r--r-- | include/sys/syslog.h | 2 | ||||
-rw-r--r-- | libc/misc/syslog/syslog.c | 2 | ||||
-rw-r--r-- | libc/sysdeps/linux/common/ssp.c | 121 |
4 files changed, 68 insertions, 61 deletions
diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in index f57109584..6a590ac54 100644 --- a/extra/Configs/Config.in +++ b/extra/Configs/Config.in @@ -2139,8 +2139,8 @@ config SSP_QUICK_CANARY choice prompt "Propolice protection blocking signal" depends on UCLIBC_HAS_SSP - default PROPOLICE_BLOCK_ABRT if ! DODEBUG - default PROPOLICE_BLOCK_SEGV if DODEBUG + depends on DODEBUG + default PROPOLICE_BLOCK_SEGV help "abort" use SIGABRT to block offending programs. This is the default implementation. diff --git a/include/sys/syslog.h b/include/sys/syslog.h index 29a12332e..fb8c500e1 100644 --- a/include/sys/syslog.h +++ b/include/sys/syslog.h @@ -179,14 +179,12 @@ __BEGIN_DECLS This function is a possible cancellation point and therefore not marked with __THROW. */ extern void closelog (void); -libc_hidden_proto(closelog) /* Open connection to system logger. This function is a possible cancellation point and therefore not marked with __THROW. */ extern void openlog (__const char *__ident, int __option, int __facility); -libc_hidden_proto(openlog) /* Set the log mask level. */ extern int setlogmask (int __mask) __THROW; diff --git a/libc/misc/syslog/syslog.c b/libc/misc/syslog/syslog.c index ce4c44a7a..1ab470700 100644 --- a/libc/misc/syslog/syslog.c +++ b/libc/misc/syslog/syslog.c @@ -175,7 +175,6 @@ openlog(const char *ident, int logstat, int logfac) openlog_intern(ident, logstat, logfac); __UCLIBC_MUTEX_UNLOCK(mylock); } -libc_hidden_def(openlog) /* * syslog, vsyslog -- @@ -330,7 +329,6 @@ closelog(void) closelog_intern(0); /* 0: reset LogXXX globals to default */ __UCLIBC_MUTEX_UNLOCK(mylock); } -libc_hidden_def(closelog) /* setlogmask -- set the log mask level */ int setlogmask(int pmask) 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 |