Submitted By: Robert Connolly <robert at linuxfromscratch dot org> (ashes)
Date: 2005-04-24
Initial Package Version: 2.3.4
Upstream Status: Not submitted
Origin: http://www.research.ibm.com/trl/projects/security/ssp/
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/sys/stack_protector.c
http://uclibc.org/cgi-bin/viewcvs.cgi/trunk/uClibc/libc/sysdeps/linux/common/ssp.c
Description: Stack Smashing Protector - This patch adds SSP functions to Glibc.

This patch depends on the Glibc arc4random patch.

Also see:
http://www.linuxfromscratch.org/hlfs/
http://www.linuxfromscratch.org/hints/downloads/files/ssp.txt

diff -Naur glibc-2.3.4.orig/sysdeps/generic/libc-start.c glibc-2.3.4/sysdeps/generic/libc-start.c
--- glibc-2.3.4.orig/sysdeps/generic/libc-start.c	2004-03-31 01:46:43.000000000 +0000
+++ glibc-2.3.4/sysdeps/generic/libc-start.c	2005-02-12 17:26:49.470416840 +0000
@@ -188,6 +188,9 @@
     GLRO(dl_debug_printf) ("\ntransferring control: %s\n\n", argv[0]);
 #endif
 
+  void __guard_setup(void) __attribute__ ((constructor));
+  __guard_setup ();
+
 #ifdef HAVE_CLEANUP_JMP_BUF
   /* Memory for the cancellation buffer.  */
   struct pthread_unwind_buf unwind_buf;
diff -Naur glibc-2.3.4.orig/sysdeps/unix/sysv/linux/Dist glibc-2.3.4/sysdeps/unix/sysv/linux/Dist
--- glibc-2.3.4.orig/sysdeps/unix/sysv/linux/Dist	2004-06-30 07:58:38.000000000 +0000
+++ glibc-2.3.4/sysdeps/unix/sysv/linux/Dist	2005-02-12 17:26:49.473416384 +0000
@@ -1,3 +1,4 @@
+stack_protector.c
 bits/initspin.h
 cmsg_nxthdr.c
 dl-brk.c
diff -Naur glibc-2.3.4.orig/sysdeps/unix/sysv/linux/Makefile glibc-2.3.4/sysdeps/unix/sysv/linux/Makefile
--- glibc-2.3.4.orig/sysdeps/unix/sysv/linux/Makefile	2004-10-04 23:29:06.000000000 +0000
+++ glibc-2.3.4/sysdeps/unix/sysv/linux/Makefile	2005-02-12 17:26:49.476415928 +0000
@@ -1,5 +1,5 @@
 ifeq ($(subdir),csu)
-sysdep_routines += errno-loc
+sysdep_routines += errno-loc stack_protector
 endif
 
 ifeq ($(subdir),assert)
diff -Naur glibc-2.3.4.orig/sysdeps/unix/sysv/linux/Versions glibc-2.3.4/sysdeps/unix/sysv/linux/Versions
--- glibc-2.3.4.orig/sysdeps/unix/sysv/linux/Versions	2004-10-22 19:57:45.000000000 +0000
+++ glibc-2.3.4/sysdeps/unix/sysv/linux/Versions	2005-02-12 17:26:49.479415472 +0000
@@ -108,6 +108,7 @@
   GLIBC_2.3.2 {
     # New kernel interfaces.
     epoll_create; epoll_ctl; epoll_wait;
+    __guard; __guard_setup; __stack_smash_handler;
   }
   GLIBC_2.3.3 {
     gnu_dev_major; gnu_dev_minor; gnu_dev_makedev;
diff -Naur glibc-2.3.4.orig/sysdeps/unix/sysv/linux/stack_protector.c glibc-2.3.4/sysdeps/unix/sysv/linux/stack_protector.c
--- glibc-2.3.4.orig/sysdeps/unix/sysv/linux/stack_protector.c	1970-01-01 00:00:00.000000000 +0000
+++ glibc-2.3.4/sysdeps/unix/sysv/linux/stack_protector.c	2005-02-12 18:00:25.757512648 +0000
@@ -0,0 +1,131 @@
+/*	$hlfs: stack_protector.c,v 1.7 2005/04/24 robert Exp $	*/
+
+/*
+ * Copyright (c) 2002 Hiroaki Etoh, Federico G. Schwindt, and Miodrag Vallat.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* One of these things is not like the other... */
+
+/*
+ * Distributed under the terms of the GNU General Public License v2
+ * $Header: $
+ *
+ * This is a modified version of Hiroaki Etoh's stack smashing routines
+ * implemented for glibc.
+ *
+ * The following people have contributed input to this code.
+ * Ned Ludd - <solar[@]gentoo.org>
+ * Alexander Gabert - <pappy[@]gentoo.org>
+ * The PaX Team - <pageexec[@]freemail.hu>
+ * Peter S. Mazinger - <ps.m[@]gmx.net>
+ * Yoann Vandoorselaere - <yoann[@]prelude-ids.org>
+ * Robert Connolly - <robert[@]linuxfromscratch.org>
+ * Cory Visi <cory@visi.name>
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h> /* For arc4random() */
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+#include <syslog.h>
+
+#include <sys/types.h>
+#include <sys/un.h>
+#include <sys/time.h>
+
+#ifdef __PROPOLICE_BLOCK_SEGV__
+#define SSP_SIGTYPE SIGSEGV
+#elif __PROPOLICE_BLOCK_KILL__
+#define SSP_SIGTYPE SIGKILL
+#else
+#define SSP_SIGTYPE SIGABRT
+#endif
+
+unsigned long __guard = 0UL;
+
+//void __guard_setup(void) __attribute__ ((constructor));
+void __guard_setup(void)
+{
+	int	i=0, fd=0;
+	size_t	size;
+	struct	timeval tv;
+
+	if (__guard != 0UL)
+		return;
+
+	__guard = 0xFF0A0D00UL;
+	/* Always start with the time. */
+	gettimeofday(&tv, NULL);
+	__guard ^= tv.tv_usec ^ tv.tv_sec;
+
+#if defined(HAVE_ARC4RANDOM) /* From <stdlib.h> */
+	for (i = 0; i < sizeof(__guard) / 4; i ++) {
+		size = sizeof(unsigned long);
+		if ((__guard = (int)(arc4randomII())) == (-1))
+			break;
+	}
+#else
+	if (i < sizeof(__guard) / 4) {
+	fd = open("/dev/urandom", O_RDONLY);
+		if (fd != (-1)) {
+			size = read(fd, (char *) &__guard, sizeof(__guard));
+			close(fd);
+			if (size == sizeof(__guard))
+				return;
+		}
+	}
+#endif
+}
+
+//void __stack_smash_handler(char func[], int damaged __attribute__ ((unused)));
+void __stack_smash_handler(char func[], int damaged)
+{
+	extern char *__progname;
+	const char message[] = ": stack smashing attack in function ";
+	struct sigaction sa;
+	sigset_t mask;
+
+	sigfillset(&mask);
+
+	sigdelset(&mask, SSP_SIGTYPE);	/* Block all signal handlers */
+	sigprocmask(SIG_BLOCK, &mask, NULL);	/* except SIGABRT */
+
+	/* print error message to stderr and syslog */
+	fprintf(stderr, "%s%s%s()\n", __progname, message, func);
+	syslog(LOG_INFO, "%s%s%s()", __progname, message, func);
+
+	/* Make the default handler is associated with the signal handler */
+	memset(&sa, 0, sizeof(struct sigaction));
+	sigfillset(&sa.sa_mask);	/* Block all signals */
+	sa.sa_flags = 0;
+	sa.sa_handler = SIG_DFL;
+	sigaction(SSP_SIGTYPE, &sa, NULL);
+	(void) kill(getpid(), SSP_SIGTYPE);
+	_exit(127);
+}
