Stack protector broken in gcc41?

Hasso Tepper hasso at estpak.ee
Tue Apr 15 06:58:43 PDT 2008


Matthew Dillon wrote:
> :>     leaf:/archive/FreeBSD-current/src/lib/libc/sys/stack_protector.c
> :
> :Yeah, but should we take care of preserving symbols for old stuff as
> : well? We would break binaries compiled with gcc34 otherwise?
> :
> :--
> :Hasso Tepper
>
>     Yah, I think it should be possible to have both.

OK, the patch attached. Someone with gcc34, please test, I haven't 
compiled gcc34 for ages.

-- 
Hasso Tepper
diff --git a/lib/libc/sys/stack_protector.c b/lib/libc/sys/stack_protector.c
--- a/lib/libc/sys/stack_protector.c
+++ b/lib/libc/sys/stack_protector.c
@@ -37,10 +37,17 @@
 #include <unistd.h>
 #include "un-namespace.h"
 
+static void __guard_setup(void) __attribute__ ((constructor));
+static void __fail(const char *);
+void __stack_chk_fail(void);
+void __chk_fail(void);
+void __stack_chk_fail_local(void);
+
+long __stack_chk_guard[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+
+/* For compatibility with stack protector used by our gcc34. */
 void __stack_smash_handler(char func[], int damaged);
-static void __guard_setup(void) __attribute__ ((constructor));
-
-long __guard[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+extern __typeof(__stack_chk_guard) __guard __attribute__ ((alias ("__stack_chk_guard")));
 
 static void
 __guard_setup(void)
@@ -48,12 +55,12 @@
     int fd;
     ssize_t size;
 
-    if (__guard[0] != 0)
+    if (__stack_chk_guard[0] != 0)
 	return;
     if ((fd = _open ("/dev/urandom", 0)) >= 0) {
-	size = _read (fd, (char*)&__guard, sizeof(__guard));
+	size = _read (fd, (char*)&__stack_chk_guard, sizeof(__stack_chk_guard));
 	_close (fd);
-	if (size == sizeof(__guard))
+	if (size == sizeof(__stack_chk_guard))
 	    return;
     }
 
@@ -61,20 +68,25 @@
      * If a random generator can't be used, the protector switches the
      * guard to the "terminator canary"
      */
-    ((char*)__guard)[0] = 0;
-    ((char*)__guard)[1] = 0;
-    ((char*)__guard)[2] = '\n';
-    ((char*)__guard)[3] = 255;
+    ((char*)__stack_chk_guard)[0] = 0;
+    ((char*)__stack_chk_guard)[1] = 0;
+    ((char*)__stack_chk_guard)[2] = '\n';
+    ((char*)__stack_chk_guard)[3] = 255;
 }
 
-void
-__stack_smash_handler(char func[], int damaged  __unused)
+static void
+__fail(const char *msg)
 {
-    static const char message[] = "stack overflow in function %s";
     struct sigaction sa;
+    sigset_t mask;
 
-    /* this may fail on a chroot jail, though luck */
-    syslog(LOG_CRIT, message, func);
+    /* Immediately block all signal handlers from running code */
+    sigfillset(&mask);
+    sigdelset(&mask, SIGABRT);
+    sigprocmask(SIG_BLOCK, &mask, NULL);
+
+    /* This may fail on a chroot jail... */
+    syslog(LOG_CRIT, msg);
 
     bzero(&sa, sizeof(struct sigaction));
     sigemptyset(&sa.sa_mask);
@@ -86,3 +98,30 @@
 
     _exit(127);
 }
+
+void
+__stack_smash_handler(char func[], int damaged  __unused)
+{
+    static char buf[128];
+
+    vsnprintf(buf, sizeof(buf), "stack overflow in function %s", func);
+    __fail(buf);
+}
+
+void
+__stack_chk_fail(void)
+{
+    __fail("stack overflow detected; terminated");
+}
+
+void
+__chk_fail(void)
+{
+    __fail("buffer overflow detected; terminated");
+}
+
+void
+__stack_chk_fail_local(void)
+{
+    __stack_chk_fail();
+}




More information about the Users mailing list