Browse Source

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>
Peter S. Mazinger 13 years ago
parent
commit
5c7e1909e1
4 changed files with 68 additions and 61 deletions
  1. 2 2
      extra/Configs/Config.in
  2. 0 2
      include/sys/syslog.h
  3. 0 2
      libc/misc/syslog/syslog.c
  4. 66 55
      libc/sysdeps/linux/common/ssp.c

+ 2 - 2
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.

+ 0 - 2
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;

+ 0 - 2
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)

+ 66 - 55
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