summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux/common
diff options
context:
space:
mode:
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