summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux/common
diff options
context:
space:
mode:
authorPeter S. Mazinger <ps.m@gmx.net>2011-04-15 00:19:28 +0200
committerBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2012-06-15 14:00:37 +0200
commit5c7e1909e1124c1cfc8251c158f3fb5301cdb1a5 (patch)
tree3d082af80da251f2c15c31080f78087345b66b05 /libc/sysdeps/linux/common
parentc9a9baab4ff9ef22ee43e5e2b394b4d78980b7e0 (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/common')
-rw-r--r--libc/sysdeps/linux/common/ssp.c121
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