diff options
-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 |