Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 28 Jul 2005 01:38:42 +0200
From:      Jeremie Le Hen <jeremie@le-hen.org>
To:        freebsd-hackers@FreeBSD.org
Subject:   Re: ProPolice symbols in libc or libssp ?
Message-ID:  <20050727233842.GW1610@obiwan.tataz.chchile.org>
In-Reply-To: <20050727000054.GA15018@britannica.bec.de>
References:  <20050705153933.GP73907@obiwan.tataz.chchile.org> <20050726232645.GN1610@obiwan.tataz.chchile.org> <20050727000054.GA15018@britannica.bec.de>

next in thread | previous in thread | raw e-mail | index | archive | help

--+jhVVhN62yS6hEJ8
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi,

> > Being full of enthusiasm, I checked if by chance libraries could have
> > dynamic object dependencies.  It appears this is not the case, but
> > since I'm neither a GCC nor binutils hacker, maybe there is a way to
> > achieve this.  This is the purpose of this email ?
> 
> What you have been smoking? Dynamic libraries surely can depend on other
> objects :-) Just link libc with -lssp, given that libssp should be
> self-contained or any other library you want to have propolice in
> against ssp. Static libraries are not an issue either, since you can
> simply add the object file. If you look around, you might even find some
> programs which allow you to add the dependency into an existing library,
> which would be perfect for libc.

(Sorry, you guys are maybe fed up with ProPolice and I'm sending a huge
mail again, but I have three questions.  Nevertheless, I would be glad
if someone with some bigger experience could take some time to answer
them.)

Eheh, I've not been smoking anything, maybe should I. ;-)


1)
In fact I've been misleaded because I modified the GCC configuration
(FBSD_LIB_SPEC in contrib/gcc/config/freebsd-spec.h) to make it
automatically link against libssp and I supposed wrongly this would
link programs _and_ libraries with libssp.  When buildworld was
completed, I checked this with ldd(1), that's why I thought it wasn't
possible to have libraries depending on other objects (installworld not
done that's why libssp is not resolved) :
%%%
    jarjarbinks# ldd /usr/obj/usr/src/bin/cat/cat
    /usr/obj/usr/src/bin/cat/cat:
            libssp.so.1 => not found (0x0)
            libc.so.6 => /lib/libc.so.6 (0x3137b000)
    jarjarbinks# ldd /usr/obj/usr/src/lib/libz/libz.so.3
    /usr/obj/usr/src/lib/libz/libz.so.3:
%%%
It seems that LIB_SPEC macro content is used only when linking programs,
not libraries, although the GCC Internals book states that it is used
whenever the linker is used [1].  I can understand that each library
should not be linked against libc, and that's why ld(1) isn't called
with LIB_SPEC macro when linking shared libraries.  But how should I do
to have shared libraries linked against libssp ?  Use LDADD make
variable (see question 2) ?



2)
Secondly, after digging a bit more, I thought that I could replace the
GCC's freebsd-spec.h hack by using the LDADD make variable.  The
advantage is that it will make import of next GCC release easier.
Furthermore, it would make me sure that libraries are really linked with
libssp (see question 1).  The drawback is that this will be a mess
for ports to handle this because their tree is used through numerous
FreeBSD major branches : this would require to test that
"${CC} ${CFLAGS}" actually handles stack protector and add -lssp
depending on the result.  Additionaly, I would say that only GCC is able
to really know when it is needed to link against libssp or not, since
the make system will either have a weak assumption of this or need some
black magic as described above for ports.



3)
Finally, my libssp requires libc because I use sysctl(3), syslog(3) and
a few other functions.  I resolved the problem of circular dependancies
with weak dependancies : libc includes libssp source file but with
different symbol names to avoid conflicts.  Then I create weak references
for the real SSP symbols names (see attached patch for an illustration).
OTOH, while I was documenting on GCC, I saw they use something like
"-lgcc -lc -lgcc" (see macro LINK_GCC_C_SEQUENCE_SPEC from [1]).  Is it
something possible for libssp, or is it simply a hack that should be
avoided ?


If you are still reading at this point, thanks :-).
I hope to not have forgotten anything or I will need to post again :).

Regards,

[1] http://gcc.gnu.org/onlinedocs/gccint/Driver.html
-- 
Jeremie Le Hen
< jeremie at le-hen dot org >< ttz at chchile dot org >

--+jhVVhN62yS6hEJ8
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="libssp.diff"

Index: lib/Makefile
===================================================================
RCS file: /nfs/obiwan/cvs/src/lib/Makefile,v
retrieving revision 1.206
diff -u -p -u -p -r1.206 Makefile
--- lib/Makefile	14 Jul 2005 17:59:50 -0000	1.206
+++ lib/Makefile	26 Jul 2005 16:41:42 -0000
@@ -32,8 +32,8 @@ SUBDIR=	${_csu} libcom_err libcrypt libk
 	libipx libkiconv libmagic libmemstat libmenu ${_libmilter} ${_libmp} \
 	${_libncp} ${_libngatm} libopie libpam libpanel libpcap \
 	libpmc ${_libpthread} ${_libsdp} ${_libsm} ${_libsmb} ${_libsmdb} \
-	${_libsmutil} libstand libtelnet ${_libthr} ${_libthread_db} libufs \
-	libugidfw ${_libusbhid} ${_libvgl} libwrap liby libz ${_bind}
+	${_libsmutil} libssp libstand libtelnet ${_libthr} ${_libthread_db} \
+	libufs libugidfw ${_libusbhid} ${_libvgl} libwrap liby libz ${_bind}
 
 .if exists(${.CURDIR}/csu/${MACHINE_ARCH}-elf)
 _csu=csu/${MACHINE_ARCH}-elf
Index: lib/libc/sys/Makefile.inc
===================================================================
RCS file: /nfs/obiwan/cvs/src/lib/libc/sys/Makefile.inc,v
retrieving revision 1.113
diff -u -p -u -p -r1.113 Makefile.inc
--- lib/libc/sys/Makefile.inc	7 Jul 2005 18:17:55 -0000	1.113
+++ lib/libc/sys/Makefile.inc	26 Jul 2005 19:02:49 -0000
@@ -2,7 +2,7 @@
 # $FreeBSD: src/lib/libc/sys/Makefile.inc,v 1.113 2005/07/07 18:17:55 jhb Exp $
 
 # sys sources
-.PATH: ${.CURDIR}/${MACHINE_ARCH}/sys ${.CURDIR}/sys
+.PATH: ${.CURDIR}/${MACHINE_ARCH}/sys ${.CURDIR}/sys ${.CURDIR}/../libssp
 
 # Include the generated makefile containing the *complete* list
 # of syscall names in MIASM.
@@ -23,6 +23,9 @@ SRCS+=	ftruncate.c lseek.c mmap.c pread.
 # Add machine dependent asm sources:
 SRCS+=${MDASM}
 
+# Include libssp symbols.
+SRCS+=	ssp.c
+
 # Look though the complete list of syscalls (MIASM) for names that are
 # not defined with machine dependent implementations (MDASM) and are
 # not declared for no generation of default code (NOASM).  Add each
Index: lib/libssp/Makefile
===================================================================
RCS file: lib/libssp/Makefile
diff -N lib/libssp/Makefile
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ lib/libssp/Makefile	26 Jul 2005 18:42:21 -0000
@@ -0,0 +1,14 @@
+#
+# $Id$
+#
+
+SHLIB_MAJOR=	1
+LIB=		ssp
+SHLIBDIR?=	/lib
+
+SRCS=		ssp.c
+CFLAGS+=	-DLIBSSP
+
+PRECIOUSLIB=
+
+.include <bsd.lib.mk>
Index: lib/libssp/ssp.c
===================================================================
RCS file: lib/libssp/ssp.c
diff -N lib/libssp/ssp.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ lib/libssp/ssp.c	27 Jul 2005 09:03:17 -0000
@@ -0,0 +1,118 @@
+/*
+ * 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.
+ *
+ */
+
+#if defined(LIBC_SCCS) && !defined(list)
+static char rcsid[] = "$OpenBSD: stack_protector.c,v 1.7 2004/09/14 22:19:30 deraadt Exp $";
+#endif
+
+#include <sys/cdefs.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <signal.h>
+#include <strings.h>
+#include <syslog.h>
+#include <unistd.h>
+
+/*
+ * Largest pointers of FreeBSD supported architectures are 64bits.
+ * Let's say it's 2 * sizeof(long).
+ */
+#define	__GUARD_SIZE 2
+
+#ifdef LIBSSP
+long ___ssp_guard[__GUARD_SIZE] = { 0 };
+void ___ssp_stack_smash_handler(char func[],
+				int damaged __attribute__((unused)));
+__weak_reference(___ssp_guard, __guard);
+__weak_reference(___ssp_stack_smash_handler, __stack_smash_handler);
+#else
+long ___guard[__GUARD_SIZE] = { 0 };
+void ___stack_smash_handler(char func[],
+			    int damaged __attribute__((unused)));
+__weak_reference(___guard, __guard);
+__weak_reference(___stack_smash_handler, __stack_smash_handler);
+#endif
+static void __guard_setup(void) __attribute__ ((constructor));
+
+static void
+__guard_setup(void)
+{
+	int i, mib[2];
+	size_t len;
+#ifdef LIBSSP
+	long *guard = ___ssp_guard;
+#else
+	long *guard = ___guard;
+#endif
+
+	if (guard[0] != 0)
+		return;
+	mib[0] = CTL_KERN;
+	mib[1] = KERN_ARND;
+
+	len = sizeof(long);
+	for (i = 0; i < __GUARD_SIZE; i++)
+		if (sysctl(mib, 2, &guard[i], &len, NULL, 0) == -1) {
+			/* Use the terminator canary as a fallback method. */
+			((char *)guard)[0] = '\0';
+			((char *)guard)[1] = '\0';
+			((char *)guard)[2] = '\n';
+			((char *)guard)[3] = '\xff';
+			break;
+		}
+}
+
+void
+#ifdef LIBSSP
+___ssp_stack_smash_handler(char func[], int damaged)
+#else
+___stack_smash_handler(char func[], int damaged)
+#endif
+{
+	const char message[] = "stack overflow in function %s";
+	struct sigaction sa;
+	sigset_t mask;
+
+	/* 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, though luck. */
+	syslog(LOG_CRIT, message, func);
+
+	bzero(&sa, sizeof(struct sigaction));
+	sigemptyset(&sa.sa_mask);
+	sa.sa_flags = 0;
+	sa.sa_handler = SIG_DFL;
+	sigaction(SIGABRT, &sa, NULL);
+
+	kill(getpid(), SIGABRT);
+
+	_exit(127);
+}

--+jhVVhN62yS6hEJ8--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050727233842.GW1610>