bump(sys-libs/glibc): Pull in 2.17, remove some configs from /etc

One oddity here: /etc/nsswitch.conf is setup as a postinst command in
order to avoid conflicting with baselayout once it starts installing
nsswitch.conf instead. Later glibc won't provide nsswitch.conf at all.
This commit is contained in:
Michael Marineau 2014-02-07 17:42:09 -08:00
parent 9f0170cc51
commit 7176f2aa0c
34 changed files with 5076 additions and 0 deletions

View File

@ -0,0 +1,2 @@
DIST glibc-2.17-patches-8.tar.bz2 83707 SHA256 477946a4915dcd0cc0565ff8532d219e2ee868f6e821ea71ce579652d01ccbb3 SHA512 6675357e62b554d9d0f8ef70341b8038f8f89591fba384bc3783ef81aead0532486e2218af71da9c6f88a3b8b382edec81bed36eb636ee231eac80e111acbfd8 WHIRLPOOL 946f431b28ec60cc61d44364187f64a2d6e92ed7c9071126cf70277843c656de4dfac9f184f572f9a72c0cb452d879cdb7aca5b9f92f8ff02a8b1a521fffef43
DIST glibc-2.17.tar.xz 10981956 SHA256 6914e337401e0e0ade23694e1b2c52a5f09e4eda3270c67e7c3ba93a89b5b23e SHA512 384e54037daaa344a26ce58242acc3f9a249d0765088d18a540a305745afa33ae6dec4024adae958eacd7100be9c713d117260ace8340f6d8c8396dbde4868d2 WHIRLPOOL 9b98c1c298aeff607aaa554341c300c15491b7314f127524fc5c048c67c5059daaf706e6cf206bb69213d5307e37bed87137ab46f504d8072bb778310081fc23

View File

@ -0,0 +1,315 @@
/* Copyright (C) 2004, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
/* Copyright (C) 2006-2008 Gentoo Foundation Inc.
* License terms as above.
*
* Hardened Gentoo SSP and FORTIFY handler
*
* An SSP failure handler that does not use functions from the rest of
* glibc; it uses the INTERNAL_SYSCALL methods directly. This ensures
* no possibility of recursion into the handler.
*
* Direct all bug reports to http://bugs.gentoo.org/
*
* Re-written from the glibc-2.3 Hardened Gentoo SSP handler
* by Kevin F. Quinn - <kevquinn[@]gentoo.org>
*
* The following people contributed to the glibc-2.3 Hardened
* Gentoo SSP and FORTIFY handler, from which this implementation draws much:
*
* 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>
* Mike Frysinger <vapier[@]gentoo.org>
* Magnus Granberg <zorry[@]ume.nu>
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sysdep-cancel.h>
#include <sys/syscall.h>
#include <bp-checks.h>
#include <kernel-features.h>
#include <alloca.h>
/* from sysdeps */
#include <socketcall.h>
/* for the stuff in bits/socket.h */
#include <sys/socket.h>
#include <sys/un.h>
/* Sanity check on SYSCALL macro names - force compilation
* failure if the names used here do not exist
*/
#if !defined __NR_socketcall && !defined __NR_socket
# error Cannot do syscall socket or socketcall
#endif
#if !defined __NR_socketcall && !defined __NR_connect
# error Cannot do syscall connect or socketcall
#endif
#ifndef __NR_write
# error Cannot do syscall write
#endif
#ifndef __NR_close
# error Cannot do syscall close
#endif
#ifndef __NR_getpid
# error Cannot do syscall getpid
#endif
#ifndef __NR_kill
# error Cannot do syscall kill
#endif
#ifndef __NR_exit
# error Cannot do syscall exit
#endif
#ifdef SSP_SMASH_DUMPS_CORE
# define ENABLE_SSP_SMASH_DUMPS_CORE 1
# if !defined _KERNEL_NSIG && !defined _NSIG
# error No _NSIG or _KERNEL_NSIG for rt_sigaction
# endif
# if !defined __NR_sigaction && !defined __NR_rt_sigaction
# error Cannot do syscall sigaction or rt_sigaction
# endif
/* Although rt_sigaction expects sizeof(sigset_t) - it expects the size
* of the _kernel_ sigset_t which is not the same as the user sigset_t.
* Most arches have this as _NSIG bits - mips has _KERNEL_NSIG bits for
* some reason.
*/
# ifdef _KERNEL_NSIG
# define _SSP_NSIG _KERNEL_NSIG
# else
# define _SSP_NSIG _NSIG
# endif
#else
# define _SSP_NSIG 0
# define ENABLE_SSP_SMASH_DUMPS_CORE 0
#endif
/* Define DO_SIGACTION - default to newer rt signal interface but
* fallback to old as needed.
*/
#ifdef __NR_rt_sigaction
# define DO_SIGACTION(signum, act, oldact) \
INLINE_SYSCALL(rt_sigaction, 4, signum, act, oldact, _SSP_NSIG/8)
#else
# define DO_SIGACTION(signum, act, oldact) \
INLINE_SYSCALL(sigaction, 3, signum, act, oldact)
#endif
/* Define DO_SOCKET/DO_CONNECT functions to deal with socketcall vs socket/connect */
#if defined(__NR_socket) && defined(__NR_connect)
# define USE_OLD_SOCKETCALL 0
#else
# define USE_OLD_SOCKETCALL 1
#endif
/* stub out the __NR_'s so we can let gcc optimize away dead code */
#ifndef __NR_socketcall
# define __NR_socketcall 0
#endif
#ifndef __NR_socket
# define __NR_socket 0
#endif
#ifndef __NR_connect
# define __NR_connect 0
#endif
#define DO_SOCKET(result, domain, type, protocol) \
do { \
if (USE_OLD_SOCKETCALL) { \
socketargs[0] = domain; \
socketargs[1] = type; \
socketargs[2] = protocol; \
socketargs[3] = 0; \
result = INLINE_SYSCALL(socketcall, 2, SOCKOP_socket, socketargs); \
} else \
result = INLINE_SYSCALL(socket, 3, domain, type, protocol); \
} while (0)
#define DO_CONNECT(result, sockfd, serv_addr, addrlen) \
do { \
if (USE_OLD_SOCKETCALL) { \
socketargs[0] = sockfd; \
socketargs[1] = (unsigned long int)serv_addr; \
socketargs[2] = addrlen; \
socketargs[3] = 0; \
result = INLINE_SYSCALL(socketcall, 2, SOCKOP_connect, socketargs); \
} else \
result = INLINE_SYSCALL(connect, 3, sockfd, serv_addr, addrlen); \
} while (0)
#ifndef _PATH_LOG
# define _PATH_LOG "/dev/log"
#endif
static const char path_log[] = _PATH_LOG;
/* For building glibc with SSP switched on, define __progname to a
* constant if building for the run-time loader, to avoid pulling
* in more of libc.so into ld.so
*/
#ifdef IS_IN_rtld
static char *__progname = "<rtld>";
#else
extern char *__progname;
#endif
/* Common handler code, used by chk_fail
* Inlined to ensure no self-references to the handler within itself.
* Data static to avoid putting more than necessary on the stack,
* to aid core debugging.
*/
__attribute__ ((__noreturn__ , __always_inline__))
static inline void
__hardened_gentoo_chk_fail(char func[], int damaged)
{
#define MESSAGE_BUFSIZ 256
static pid_t pid;
static int plen, i;
static char message[MESSAGE_BUFSIZ];
static const char msg_ssa[] = ": buffer overflow attack";
static const char msg_inf[] = " in function ";
static const char msg_ssd[] = "*** buffer overflow detected ***: ";
static const char msg_terminated[] = " - terminated\n";
static const char msg_report[] = "Report to http://bugs.gentoo.org/\n";
static const char msg_unknown[] = "<unknown>";
static int log_socket, connect_result;
static struct sockaddr_un sock;
static unsigned long int socketargs[4];
/* Build socket address
*/
sock.sun_family = AF_UNIX;
i = 0;
while ((path_log[i] != '\0') && (i<(sizeof(sock.sun_path)-1))) {
sock.sun_path[i] = path_log[i];
i++;
}
sock.sun_path[i] = '\0';
/* Try SOCK_DGRAM connection to syslog */
connect_result = -1;
DO_SOCKET(log_socket, AF_UNIX, SOCK_DGRAM, 0);
if (log_socket != -1)
DO_CONNECT(connect_result, log_socket, &sock, sizeof(sock));
if (connect_result == -1) {
if (log_socket != -1)
INLINE_SYSCALL(close, 1, log_socket);
/* Try SOCK_STREAM connection to syslog */
DO_SOCKET(log_socket, AF_UNIX, SOCK_STREAM, 0);
if (log_socket != -1)
DO_CONNECT(connect_result, log_socket, &sock, sizeof(sock));
}
/* Build message. Messages are generated both in the old style and new style,
* so that log watchers that are configured for the old-style message continue
* to work.
*/
#define strconcat(str) \
{i=0; while ((str[i] != '\0') && ((i+plen)<(MESSAGE_BUFSIZ-1))) \
{\
message[plen+i]=str[i];\
i++;\
}\
plen+=i;}
/* R.Henderson post-gcc-4 style message */
plen = 0;
strconcat(msg_ssd);
if (__progname != (char *)0)
strconcat(__progname)
else
strconcat(msg_unknown);
strconcat(msg_terminated);
/* Write out error message to STDERR, to syslog if open */
INLINE_SYSCALL(write, 3, STDERR_FILENO, message, plen);
if (connect_result != -1)
INLINE_SYSCALL(write, 3, log_socket, message, plen);
/* Dr. Etoh pre-gcc-4 style message */
plen = 0;
if (__progname != (char *)0)
strconcat(__progname)
else
strconcat(msg_unknown);
strconcat(msg_ssa);
strconcat(msg_inf);
if (func != NULL)
strconcat(func)
else
strconcat(msg_unknown);
strconcat(msg_terminated);
/* Write out error message to STDERR, to syslog if open */
INLINE_SYSCALL(write, 3, STDERR_FILENO, message, plen);
if (connect_result != -1)
INLINE_SYSCALL(write, 3, log_socket, message, plen);
/* Direct reports to bugs.gentoo.org */
plen=0;
strconcat(msg_report);
message[plen++]='\0';
/* Write out error message to STDERR, to syslog if open */
INLINE_SYSCALL(write, 3, STDERR_FILENO, message, plen);
if (connect_result != -1)
INLINE_SYSCALL(write, 3, log_socket, message, plen);
if (log_socket != -1)
INLINE_SYSCALL(close, 1, log_socket);
/* Suicide */
pid = INLINE_SYSCALL(getpid, 0);
if (ENABLE_SSP_SMASH_DUMPS_CORE) {
static struct sigaction default_abort_act;
/* Remove any user-supplied handler for SIGABRT, before using it */
default_abort_act.sa_handler = SIG_DFL;
default_abort_act.sa_sigaction = NULL;
__sigfillset(&default_abort_act.sa_mask);
default_abort_act.sa_flags = 0;
if (DO_SIGACTION(SIGABRT, &default_abort_act, NULL) == 0)
INLINE_SYSCALL(kill, 2, pid, SIGABRT);
}
/* Note; actions cannot be added to SIGKILL */
INLINE_SYSCALL(kill, 2, pid, SIGKILL);
/* In case the kill didn't work, exit anyway
* The loop prevents gcc thinking this routine returns
*/
while (1)
INLINE_SYSCALL(exit, 0);
}
__attribute__ ((__noreturn__))
void __chk_fail(void)
{
__hardened_gentoo_chk_fail(NULL, 0);
}

View File

@ -0,0 +1,30 @@
Prevent default-fPIE from confusing configure into thinking
PIC code is default. This causes glibc to build both PIC and
non-PIC code as normal, which on the hardened compiler generates
PIC and PIE.
Patch by Kevin F. Quinn <kevquinn@gentoo.org>
Fixed for glibc 2.10 by Magnus Granberg <zorry@ume.nu>
--- configure.in
+++ configure.in
@@ -2145,7 +2145,7 @@
# error PIC is default.
#endif
EOF
-if eval "${CC-cc} -S conftest.c 2>&AS_MESSAGE_LOG_FD 1>&AS_MESSAGE_LOG_FD"; then
+if eval "${CC-cc} -fno-PIE -S conftest.c 2>&AS_MESSAGE_LOG_FD 1>&AS_MESSAGE_LOG_FD"; then
libc_cv_pic_default=no
fi
rm -f conftest.*])
--- configure
+++ configure
@@ -7698,7 +7698,7 @@
# error PIC is default.
#endif
EOF
-if eval "${CC-cc} -S conftest.c 2>&5 1>&5"; then
+if eval "${CC-cc} -fno-PIE -S conftest.c 2>&5 1>&5"; then
libc_cv_pic_default=no
fi
rm -f conftest.*

View File

@ -0,0 +1,274 @@
When building glibc PIE (which is not something upstream support),
several modifications are necessary to the glibc build process.
First, any syscalls in PIEs must be of the PIC variant, otherwise
textrels ensue. Then, any syscalls made before the initialisation
of the TLS will fail on i386, as the sysenter variant on i386 uses
the TLS, giving rise to a chicken-and-egg situation. This patch
defines a PIC syscall variant that doesn't use sysenter, even when the sysenter
version is normally used, and uses the non-sysenter version for the brk
syscall that is performed by the TLS initialisation. Further, the TLS
initialisation is moved in this case prior to the initialisation of
dl_osversion, as that requires further syscalls.
csu/libc-start.c: Move initial TLS initialization to before the
initialisation of dl_osversion, when INTERNAL_SYSCALL_NOSYSENTER is defined
csu/libc-tls.c: Use the no-sysenter version of sbrk when
INTERNAL_SYSCALL_NOSYSENTER is defined.
misc/sbrk.c: Define a no-sysenter version of sbrk, using the no-sysenter
version of brk - if INTERNAL_SYSCALL_NOSYSENTER is defined.
misc/brk.c: Define a no-sysenter version of brk if
INTERNAL_SYSCALL_NOSYSENTER is defined.
sysdeps/unix/sysv/linux/i386/sysdep.h: Define INTERNAL_SYSCALL_NOSYSENTER
Make INTERNAL_SYSCALL always use the PIC variant, even if not SHARED.
Patch by Kevin F. Quinn <kevquinn@gentoo.org>
Fixed for 2.10 by Magnus Granberg <zorry@ume.nu>
--- csu/libc-start.c
+++ csu/libc-start.c
@@ -28,6 +28,7 @@
extern int __libc_multiple_libcs;
#include <tls.h>
+#include <sysdep.h>
#ifndef SHARED
# include <dl-osinfo.h>
extern void __pthread_initialize_minimal (void);
@@ -129,6 +130,11 @@
# endif
_dl_aux_init (auxvec);
# endif
+# ifdef INTERNAL_SYSCALL_NOSYSENTER
+ /* Do the initial TLS initialization before _dl_osversion,
+ since the latter uses the uname syscall. */
+ __pthread_initialize_minimal ();
+# endif
# ifdef DL_SYSDEP_OSCHECK
if (!__libc_multiple_libcs)
{
@@ -138,10 +144,12 @@
}
# endif
+# ifndef INTERNAL_SYSCALL_NOSYSENTER
/* Initialize the thread library at least a bit since the libgcc
functions are using thread functions if these are available and
we need to setup errno. */
__pthread_initialize_minimal ();
+# endif
/* Set up the stack checker's canary. */
uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard ();
--- csu/libc-tls.c
+++ csu/libc-tls.c
@@ -23,6 +23,7 @@
#include <unistd.h>
#include <stdio.h>
#include <sys/param.h>
+#include <sysdep.h>
#ifdef SHARED
@@ -29,6 +30,9 @@
#error makefile bug, this file is for static only
#endif
+#ifdef INTERNAL_SYSCALL_NOSYSENTER
+extern void *__sbrk_nosysenter (intptr_t __delta);
+#endif
extern ElfW(Phdr) *_dl_phdr;
extern size_t _dl_phnum;
@@ -141,14 +145,26 @@
The initialized value of _dl_tls_static_size is provided by dl-open.c
to request some surplus that permits dynamic loading of modules with
- IE-model TLS. */
+ IE-model TLS.
+
+ Where the normal sbrk would use a syscall that needs the TLS (i386)
+ use the special non-sysenter version instead. */
#if TLS_TCB_AT_TP
tcb_offset = roundup (memsz + GL(dl_tls_static_size), tcbalign);
+# ifdef INTERNAL_SYSCALL_NOSYSENTER
+ tlsblock = __sbrk_nosysenter (tcb_offset + tcbsize + max_align);
+# else
tlsblock = __sbrk (tcb_offset + tcbsize + max_align);
+# endif
#elif TLS_DTV_AT_TP
tcb_offset = roundup (tcbsize, align ?: 1);
+# ifdef INTERNAL_SYSCALL_NOSYSENTER
+ tlsblock = __sbrk_nosysenter (tcb_offset + memsz + max_align
+ + TLS_PRE_TCB_SIZE + GL(dl_tls_static_size));
+# else
tlsblock = __sbrk (tcb_offset + memsz + max_align
+ TLS_PRE_TCB_SIZE + GL(dl_tls_static_size));
+# endif
tlsblock += TLS_PRE_TCB_SIZE;
#else
/* In case a model with a different layout for the TCB and DTV
--- misc/sbrk.c
+++ misc/sbrk.c
@@ -18,6 +18,7 @@
#include <errno.h>
#include <stdint.h>
#include <unistd.h>
+#include <sysdep.h>
/* Defined in brk.c. */
extern void *__curbrk;
@@ -29,6 +30,35 @@
/* Extend the process's data space by INCREMENT.
If INCREMENT is negative, shrink data space by - INCREMENT.
Return start of new space allocated, or -1 for errors. */
+#ifdef INTERNAL_SYSCALL_NOSYSENTER
+/* This version is used by csu/libc-tls.c whem initialising the TLS
+ if the SYSENTER version requires the TLS (which it does on i386).
+ Obviously using the TLS before it is initialised is broken. */
+extern int __brk_nosysenter (void *addr);
+void *
+__sbrk_nosysenter (intptr_t increment)
+{
+ void *oldbrk;
+
+ /* If this is not part of the dynamic library or the library is used
+ via dynamic loading in a statically linked program update
+ __curbrk from the kernel's brk value. That way two separate
+ instances of __brk and __sbrk can share the heap, returning
+ interleaved pieces of it. */
+ if (__curbrk == NULL || __libc_multiple_libcs)
+ if (__brk_nosysenter (0) < 0) /* Initialize the break. */
+ return (void *) -1;
+
+ if (increment == 0)
+ return __curbrk;
+
+ oldbrk = __curbrk;
+ if (__brk_nosysenter (oldbrk + increment) < 0)
+ return (void *) -1;
+
+ return oldbrk;
+}
+#endif
void *
__sbrk (intptr_t increment)
{
--- sysdeps/unix/sysv/linux/i386/brk.c
+++ sysdeps/unix/sysv/linux/i386/brk.c
@@ -31,6 +31,30 @@
linker. */
weak_alias (__curbrk, ___brk_addr)
+#ifdef INTERNAL_SYSCALL_NOSYSENTER
+/* This version is used by csu/libc-tls.c whem initialising the TLS
+ * if the SYSENTER version requires the TLS (which it does on i386).
+ * Obviously using the TLS before it is initialised is broken. */
+int
+__brk_nosysenter (void *addr)
+{
+ void *__unbounded newbrk;
+
+ INTERNAL_SYSCALL_DECL (err);
+ newbrk = (void *__unbounded) INTERNAL_SYSCALL_NOSYSENTER (brk, err, 1,
+ __ptrvalue (addr));
+
+ __curbrk = newbrk;
+
+ if (newbrk < addr)
+ {
+ __set_errno (ENOMEM);
+ return -1;
+ }
+
+ return 0;
+}
+#endif
int
__brk (void *addr)
{
--- sysdeps/unix/sysv/linux/i386/sysdep.h
+++ sysdeps/unix/sysv/linux/i386/sysdep.h
@@ -187,7 +187,7 @@
/* The original calling convention for system calls on Linux/i386 is
to use int $0x80. */
#ifdef I386_USE_SYSENTER
-# ifdef SHARED
+# if defined SHARED || defined __PIC__
# define ENTER_KERNEL call *%gs:SYSINFO_OFFSET
# else
# define ENTER_KERNEL call *_dl_sysinfo
@@ -358,7 +358,7 @@
possible to use more than four parameters. */
#undef INTERNAL_SYSCALL
#ifdef I386_USE_SYSENTER
-# ifdef SHARED
+# if defined SHARED || defined __PIC__
# define INTERNAL_SYSCALL(name, err, nr, args...) \
({ \
register unsigned int resultvar; \
@@ -384,6 +384,18 @@
: "0" (name), "i" (offsetof (tcbhead_t, sysinfo)) \
ASMFMT_##nr(args) : "memory", "cc"); \
(int) resultvar; })
+# define INTERNAL_SYSCALL_NOSYSENTER(name, err, nr, args...) \
+ ({ \
+ register unsigned int resultvar; \
+ EXTRAVAR_##nr \
+ asm volatile ( \
+ LOADARGS_NOSYSENTER_##nr \
+ "movl %1, %%eax\n\t" \
+ "int $0x80\n\t" \
+ RESTOREARGS_NOSYSENTER_##nr \
+ : "=a" (resultvar) \
+ : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc"); \
+ (int) resultvar; })
# else
# define INTERNAL_SYSCALL(name, err, nr, args...) \
({ \
@@ -447,12 +459,20 @@
#define LOADARGS_0
#ifdef __PIC__
-# if defined I386_USE_SYSENTER && defined SHARED
+# if defined I386_USE_SYSENTER && ( defined SHARED || defined __PIC__ )
# define LOADARGS_1 \
"bpushl .L__X'%k3, %k3\n\t"
# define LOADARGS_5 \
"movl %%ebx, %4\n\t" \
"movl %3, %%ebx\n\t"
+# define LOADARGS_NOSYSENTER_1 \
+ "bpushl .L__X'%k2, %k2\n\t"
+# define LOADARGS_NOSYSENTER_2 LOADARGS_NOSYSENTER_1
+# define LOADARGS_NOSYSENTER_3 LOADARGS_3
+# define LOADARGS_NOSYSENTER_4 LOADARGS_3
+# define LOADARGS_NOSYSENTER_5 \
+ "movl %%ebx, %3\n\t" \
+ "movl %2, %%ebx\n\t"
# else
# define LOADARGS_1 \
"bpushl .L__X'%k2, %k2\n\t"
@@ -474,11 +495,18 @@
#define RESTOREARGS_0
#ifdef __PIC__
-# if defined I386_USE_SYSENTER && defined SHARED
+# if defined I386_USE_SYSENTER && ( defined SHARED || defined __PIC__ )
# define RESTOREARGS_1 \
"bpopl .L__X'%k3, %k3\n\t"
# define RESTOREARGS_5 \
"movl %4, %%ebx"
+# define RESTOREARGS_NOSYSENTER_1 \
+ "bpopl .L__X'%k2, %k2\n\t"
+# define RESTOREARGS_NOSYSENTER_2 RESTOREARGS_NOSYSENTER_1
+# define RESTOREARGS_NOSYSENTER_3 RESTOREARGS_3
+# define RESTOREARGS_NOSYSENTER_4 RESTOREARGS_3
+# define RESTOREARGS_NOSYSENTER_5 \
+ "movl %3, %%ebx"
# else
# define RESTOREARGS_1 \
"bpopl .L__X'%k2, %k2\n\t"

View File

@ -0,0 +1,168 @@
Add backwards compat support for gcc-3.x ssp ... older ssp versions
used __guard and __stack_smash_handler symbols while gcc-4.1 and newer
uses __stack_chk_guard and __stack_chk_fail.
--- config.h.in
+++ config.h.in
@@ -42,6 +42,9 @@
assembler instructions per line. Default is `;' */
#undef ASM_LINE_SEP
+/* Define if we want to enable support for old ssp symbols */
+#undef ENABLE_OLD_SSP_COMPAT
+
/* Define if not using ELF, but `.init' and `.fini' sections are available. */
#undef HAVE_INITFINI
--- configure
+++ configure
@@ -1378,6 +1378,9 @@ Optional Features:
--enable-kernel=VERSION compile for compatibility with kernel not older than
VERSION
--enable-all-warnings enable all useful warnings gcc can issue
+ --disable-old-ssp-compat
+ enable support for older ssp symbols
+ [default=no]
--enable-multi-arch enable single DSO with optimizations for multiple
architectures
--enable-experimental-malloc
@@ -6462,6 +6465,20 @@ fi
$as_echo "$libc_cv_ssp" >&6; }
+# Check whether --enable-old-ssp-compat or --disable-old-ssp-compat was given.
+if test "${enable_old_ssp_compat+set}" = set; then
+ enableval="$enable_old_ssp_compat"
+ enable_old_ssp_compat=$enableval
+else
+ enable_old_ssp_compat=no
+fi;
+if test "x$enable_old_ssp_compat" = "xyes"; then
+ cat >>confdefs.h <<\_ACEOF
+#define ENABLE_OLD_SSP_COMPAT 1
+_ACEOF
+
+fi
+
{ $as_echo "$as_me:$LINENO: checking for -fgnu89-inline" >&5
$as_echo_n "checking for -fgnu89-inline... " >&6; }
if test "${libc_cv_gnu89_inline+set}" = set; then
--- configure.in
+++ configure.in
@@ -1641,6 +1641,15 @@ fi
rm -f conftest*])
AC_SUBST(libc_cv_ssp)
+AC_ARG_ENABLE([old-ssp-compat],
+ AC_HELP_STRING([--enable-old-ssp-compat],
+ [enable support for older ssp symbols @<:@default=no@:>@]),
+ [enable_old_ssp_compat=$enableval],
+ [enable_old_ssp_compat=no])
+if test "x$enable_old_ssp_compat" = "xyes"; then
+ AC_DEFINE(ENABLE_OLD_SSP_COMPAT)
+fi
+
AC_CACHE_CHECK(for -fgnu89-inline, libc_cv_gnu89_inline, [dnl
cat > conftest.c <<EOF
int foo;
--- csu/libc-start.c
+++ csu/libc-start.c
@@ -37,6 +37,9 @@ extern void __pthread_initialize_minimal
uintptr_t __stack_chk_guard attribute_relro;
# endif
#endif
+#ifdef ENABLE_OLD_SSP_COMPAT
+uintptr_t __guard attribute_relro;
+#endif
#ifdef HAVE_PTR_NTHREADS
/* We need atomic operations. */
@@ -141,6 +145,9 @@ LIBC_START_MAIN (int (*main) (int, char
/* Set up the stack checker's canary. */
uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (_dl_random);
+#ifdef ENABLE_OLD_SSP_COMPAT
+ __guard = stack_chk_guard;
+#endif
# ifdef THREAD_SET_STACK_GUARD
THREAD_SET_STACK_GUARD (stack_chk_guard);
# else
--- csu/Versions
+++ csu/Versions
@@ -17,6 +17,12 @@ libc {
# New special glibc functions.
gnu_get_libc_release; gnu_get_libc_version;
}
+ GLIBC_2.3.2 {
+%ifdef ENABLE_OLD_SSP_COMPAT
+ # global objects and functions for the old propolice patch in gcc
+ __guard;
+%endif
+ }
GLIBC_PRIVATE {
%if HAVE___THREAD
# This version is for the TLS symbol, GLIBC_2.0 is the old object symbol.
--- debug/Versions
+++ debug/Versions
@@ -10,6 +10,12 @@ libc {
# These are to support some gcc features.
__cyg_profile_func_enter; __cyg_profile_func_exit;
}
+%ifdef ENABLE_OLD_SSP_COMPAT
+ GLIBC_2.3.2 {
+ # backwards ssp compat support; alias to __stack_chk_fail
+ __stack_smash_handler;
+ }
+%endif
GLIBC_2.3.4 {
__chk_fail;
__memcpy_chk; __memmove_chk; __mempcpy_chk; __memset_chk; __stpcpy_chk;
--- elf/rtld.c
+++ elf/rtld.c
@@ -89,6 +89,9 @@ INTDEF(_dl_argv)
in thread local area. */
uintptr_t __stack_chk_guard attribute_relro;
#endif
+#ifdef ENABLE_OLD_SSP_COMPAT
+uintptr_t __guard attribute_relro;
+#endif
/* Only exported for architectures that don't store the pointer guard
value in thread local area. */
@@ -1817,6 +1821,9 @@ ERROR: ld.so: object '%s' cannot be load
/* Set up the stack checker's canary. */
uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (_dl_random);
+#ifdef ENABLE_OLD_SSP_COMPAT
+ __guard = stack_chk_guard;
+#endif
#ifdef THREAD_SET_STACK_GUARD
THREAD_SET_STACK_GUARD (stack_chk_guard);
#else
--- elf/Versions
+++ elf/Versions
@@ -43,6 +43,12 @@ ld {
# runtime interface to TLS
__tls_get_addr;
}
+%ifdef ENABLE_OLD_SSP_COMPAT
+ GLIBC_2.3.2 {
+ # backwards ssp compat support
+ __guard;
+ }
+%endif
GLIBC_2.4 {
# stack canary
__stack_chk_guard;
--- Versions.def
+++ Versions.def
@@ -109,6 +109,9 @@ ld {
GLIBC_2.0
GLIBC_2.1
GLIBC_2.3
+%ifdef ENABLE_OLD_SSP_COMPAT
+ GLIBC_2.3.2
+%endif
GLIBC_2.4
GLIBC_PRIVATE
}

View File

@ -0,0 +1,40 @@
http://bugs.gentoo.org/292139
2009-11-08 Magnus Granberg <zorry@ume.nu>
* Makeconfig (+link): Set to +link-pie.
(+link-static): Change $(static-start-installed-name) to
S$(static-start-installed-name).
(+prector): Set to +prectorS.
(+postctor): Set to +postctorS.
--- libc/Makeconfig
+++ libc/Makeconfig
@@ -447,11 +447,12 @@
$(common-objpfx)libc% $(+postinit),$^) \
$(link-extra-libs) $(link-libc) $(+postctorS) $(+postinit)
endif
++link = $(+link-pie)
# Command for statically linking programs with the C library.
ifndef +link-static
+link-static = $(CC) -nostdlib -nostartfiles -static -o $@ \
$(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \
- $(addprefix $(csu-objpfx),$(static-start-installed-name)) \
+ $(addprefix $(csu-objpfx),S$(static-start-installed-name)) \
$(+preinit) $(+prector) \
$(filter-out $(addprefix $(csu-objpfx),start.o \
$(start-installed-name))\
@@ -549,11 +550,10 @@
ifeq ($(elf),yes)
+preinit = $(addprefix $(csu-objpfx),crti.o)
+postinit = $(addprefix $(csu-objpfx),crtn.o)
-+prector = `$(CC) --print-file-name=crtbegin.o`
-+postctor = `$(CC) --print-file-name=crtend.o`
-# Variants of the two previous definitions for linking PIE programs.
+prectorS = `$(CC) --print-file-name=crtbeginS.o`
+postctorS = `$(CC) --print-file-name=crtendS.o`
++prector = $(+prectorS)
++postctor = $(+postctorS)
+interp = $(addprefix $(elf-objpfx),interp.os)
endif
csu-objpfx = $(common-objpfx)csu/

View File

@ -0,0 +1,39 @@
2010-08-11 Magnus Granberg <zorry@ume.nu>
#332331
* Makeconfig (+link): Set to +link-pie.
(+link-static): Change $(static-start-installed-name) to
S$(static-start-installed-name).
(+prector): Set to +prectorS.
(+postctor): Set to +postctorS.
--- libc/Makeconfig
+++ libc/Makeconfig
@@ -447,11 +447,12 @@
$(common-objpfx)libc% $(+postinit),$^) \
$(link-extra-libs) $(link-libc) $(+postctorS) $(+postinit)
endif
++link = $(+link-pie)
# Command for statically linking programs with the C library.
ifndef +link-static
+link-static = $(CC) -nostdlib -nostartfiles -static -o $@ \
$(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \
- $(addprefix $(csu-objpfx),$(static-start-installed-name)) \
+ $(addprefix $(csu-objpfx),S$(static-start-installed-name)) \
$(+preinit) $(+prector) \
$(filter-out $(addprefix $(csu-objpfx),start.o \
$(start-installed-name))\
@@ -549,11 +550,10 @@
ifeq ($(elf),yes)
+preinit = $(addprefix $(csu-objpfx),crti.o)
+postinit = $(addprefix $(csu-objpfx),crtn.o)
-+prector = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtbegin.o`
-+postctor = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtend.o`
-# Variants of the two previous definitions for linking PIE programs.
+prectorS = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtbeginS.o`
+postctorS = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtendS.o`
++prector = $(+prectorS)
++postctor = $(+postctorS)
+interp = $(addprefix $(elf-objpfx),interp.os)
endif
csu-objpfx = $(common-objpfx)csu/

View File

@ -0,0 +1,39 @@
2012-11-11 Magnus Granberg <zorry@gentoo.org>
#442712
* Makeconfig (+link): Set to +link-pie.
(+link-static-before-libc): Change $(static-start-installed-name) to
S$(static-start-installed-name).
(+prector): Set to +prectorS.
(+postctor): Set to +postctorS.
--- libc/Makeconfig
+++ libc/Makeconfig
@@ -447,11 +447,12 @@
$(common-objpfx)libc% $(+postinit),$^) \
$(link-extra-libs) $(link-libc) $(+postctorS) $(+postinit)
endif
++link = $(+link-pie)
# Command for statically linking programs with the C library.
ifndef +link-static
+link-static-before-libc = $(CC) -nostdlib -nostartfiles -static -o $@ \
$(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \
- $(addprefix $(csu-objpfx),$(static-start-installed-name)) \
+ $(addprefix $(csu-objpfx),S$(static-start-installed-name)) \
$(+preinit) $(+prector) \
$(filter-out $(addprefix $(csu-objpfx),start.o \
$(start-installed-name))\
@@ -549,11 +550,10 @@
ifeq ($(elf),yes)
+preinit = $(addprefix $(csu-objpfx),crti.o)
+postinit = $(addprefix $(csu-objpfx),crtn.o)
-+prector = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtbegin.o`
-+postctor = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtend.o`
-# Variants of the two previous definitions for linking PIE programs.
+prectorS = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtbeginS.o`
+postctorS = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtendS.o`
++prector = $(+prectorS)
++postctor = $(+postctorS)
+interp = $(addprefix $(elf-objpfx),interp.os)
endif
csu-objpfx = $(common-objpfx)csu/

View File

@ -0,0 +1,42 @@
2012-11-11 Magnus Granberg <zorry@gentoo.org>
#442712
* Makeconfig (+link): Set to +link-pie.
(+link-static-before-libc): Change $(static-start-installed-name) to
S$(static-start-installed-name).
(+prector): Set to +prectorS.
(+postctor): Set to +postctorS.
--- libc/Makeconfig
+++ libc/Makeconfig
@@ -447,11 +447,12 @@
$(common-objpfx)libc% $(+postinit),$^) \
$(link-extra-libs) $(link-libc) $(+postctorS) $(+postinit)
endif
++link = $(+link-pie)
# Command for statically linking programs with the C library.
ifndef +link-static
+link-static-before-libc = $(CC) -nostdlib -nostartfiles -static -o $@ \
$(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \
- $(addprefix $(csu-objpfx),$(static-start-installed-name)) \
+ $(addprefix $(csu-objpfx),S$(static-start-installed-name)) \
$(+preinit) $(+prectorT) \
$(filter-out $(addprefix $(csu-objpfx),start.o \
$(start-installed-name))\
@@ -549,11 +550,10 @@
ifeq ($(elf),yes)
+preinit = $(addprefix $(csu-objpfx),crti.o)
+postinit = $(addprefix $(csu-objpfx),crtn.o)
-+prector = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtbegin.o`
-+postctor = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtend.o`
-# Variants of the two previous definitions for linking PIE programs.
+prectorS = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtbeginS.o`
+postctorS = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtendS.o`
++prector = $(+prectorS)
++postctor = $(+postctorS)
# Variants of the two previous definitions for statically linking programs.
+prectorT = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtbeginT.o`
+postctorT = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtend.o`
+interp = $(addprefix $(elf-objpfx),interp.os)
endif
csu-objpfx = $(common-objpfx)csu/

View File

@ -0,0 +1,314 @@
/* Copyright (C) 2004, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
/* Copyright (C) 2006-2013 Gentoo Foundation Inc.
* License terms as above.
*
* Hardened Gentoo SSP and FORTIFY handler
*
* An SSP failure handler that does not use functions from the rest of
* glibc; it uses the INTERNAL_SYSCALL methods directly. This ensures
* no possibility of recursion into the handler.
*
* Direct all bug reports to http://bugs.gentoo.org/
*
* Re-written from the glibc-2.3 Hardened Gentoo SSP handler
* by Kevin F. Quinn - <kevquinn[@]gentoo.org>
*
* The following people contributed to the glibc-2.3 Hardened
* Gentoo SSP and FORTIFY handler, from which this implementation draws much:
*
* 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>
* Mike Frysinger <vapier[@]gentoo.org>
* Magnus Granberg <zorry[@]ume.nu>
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sysdep-cancel.h>
#include <sys/syscall.h>
#include <kernel-features.h>
#include <alloca.h>
/* from sysdeps */
#include <socketcall.h>
/* for the stuff in bits/socket.h */
#include <sys/socket.h>
#include <sys/un.h>
/* Sanity check on SYSCALL macro names - force compilation
* failure if the names used here do not exist
*/
#if !defined __NR_socketcall && !defined __NR_socket
# error Cannot do syscall socket or socketcall
#endif
#if !defined __NR_socketcall && !defined __NR_connect
# error Cannot do syscall connect or socketcall
#endif
#ifndef __NR_write
# error Cannot do syscall write
#endif
#ifndef __NR_close
# error Cannot do syscall close
#endif
#ifndef __NR_getpid
# error Cannot do syscall getpid
#endif
#ifndef __NR_kill
# error Cannot do syscall kill
#endif
#ifndef __NR_exit
# error Cannot do syscall exit
#endif
#ifdef SSP_SMASH_DUMPS_CORE
# define ENABLE_SSP_SMASH_DUMPS_CORE 1
# if !defined _KERNEL_NSIG && !defined _NSIG
# error No _NSIG or _KERNEL_NSIG for rt_sigaction
# endif
# if !defined __NR_sigaction && !defined __NR_rt_sigaction
# error Cannot do syscall sigaction or rt_sigaction
# endif
/* Although rt_sigaction expects sizeof(sigset_t) - it expects the size
* of the _kernel_ sigset_t which is not the same as the user sigset_t.
* Most arches have this as _NSIG bits - mips has _KERNEL_NSIG bits for
* some reason.
*/
# ifdef _KERNEL_NSIG
# define _SSP_NSIG _KERNEL_NSIG
# else
# define _SSP_NSIG _NSIG
# endif
#else
# define _SSP_NSIG 0
# define ENABLE_SSP_SMASH_DUMPS_CORE 0
#endif
/* Define DO_SIGACTION - default to newer rt signal interface but
* fallback to old as needed.
*/
#ifdef __NR_rt_sigaction
# define DO_SIGACTION(signum, act, oldact) \
INLINE_SYSCALL(rt_sigaction, 4, signum, act, oldact, _SSP_NSIG/8)
#else
# define DO_SIGACTION(signum, act, oldact) \
INLINE_SYSCALL(sigaction, 3, signum, act, oldact)
#endif
/* Define DO_SOCKET/DO_CONNECT functions to deal with socketcall vs socket/connect */
#if defined(__NR_socket) && defined(__NR_connect)
# define USE_OLD_SOCKETCALL 0
#else
# define USE_OLD_SOCKETCALL 1
#endif
/* stub out the __NR_'s so we can let gcc optimize away dead code */
#ifndef __NR_socketcall
# define __NR_socketcall 0
#endif
#ifndef __NR_socket
# define __NR_socket 0
#endif
#ifndef __NR_connect
# define __NR_connect 0
#endif
#define DO_SOCKET(result, domain, type, protocol) \
do { \
if (USE_OLD_SOCKETCALL) { \
socketargs[0] = domain; \
socketargs[1] = type; \
socketargs[2] = protocol; \
socketargs[3] = 0; \
result = INLINE_SYSCALL(socketcall, 2, SOCKOP_socket, socketargs); \
} else \
result = INLINE_SYSCALL(socket, 3, domain, type, protocol); \
} while (0)
#define DO_CONNECT(result, sockfd, serv_addr, addrlen) \
do { \
if (USE_OLD_SOCKETCALL) { \
socketargs[0] = sockfd; \
socketargs[1] = (unsigned long int)serv_addr; \
socketargs[2] = addrlen; \
socketargs[3] = 0; \
result = INLINE_SYSCALL(socketcall, 2, SOCKOP_connect, socketargs); \
} else \
result = INLINE_SYSCALL(connect, 3, sockfd, serv_addr, addrlen); \
} while (0)
#ifndef _PATH_LOG
# define _PATH_LOG "/dev/log"
#endif
static const char path_log[] = _PATH_LOG;
/* For building glibc with SSP switched on, define __progname to a
* constant if building for the run-time loader, to avoid pulling
* in more of libc.so into ld.so
*/
#ifdef IS_IN_rtld
static char *__progname = "<rtld>";
#else
extern char *__progname;
#endif
/* Common handler code, used by chk_fail
* Inlined to ensure no self-references to the handler within itself.
* Data static to avoid putting more than necessary on the stack,
* to aid core debugging.
*/
__attribute__ ((__noreturn__ , __always_inline__))
static inline void
__hardened_gentoo_chk_fail(char func[], int damaged)
{
#define MESSAGE_BUFSIZ 256
static pid_t pid;
static int plen, i;
static char message[MESSAGE_BUFSIZ];
static const char msg_ssa[] = ": buffer overflow attack";
static const char msg_inf[] = " in function ";
static const char msg_ssd[] = "*** buffer overflow detected ***: ";
static const char msg_terminated[] = " - terminated\n";
static const char msg_report[] = "Report to http://bugs.gentoo.org/\n";
static const char msg_unknown[] = "<unknown>";
static int log_socket, connect_result;
static struct sockaddr_un sock;
static unsigned long int socketargs[4];
/* Build socket address
*/
sock.sun_family = AF_UNIX;
i = 0;
while ((path_log[i] != '\0') && (i<(sizeof(sock.sun_path)-1))) {
sock.sun_path[i] = path_log[i];
i++;
}
sock.sun_path[i] = '\0';
/* Try SOCK_DGRAM connection to syslog */
connect_result = -1;
DO_SOCKET(log_socket, AF_UNIX, SOCK_DGRAM, 0);
if (log_socket != -1)
DO_CONNECT(connect_result, log_socket, &sock, sizeof(sock));
if (connect_result == -1) {
if (log_socket != -1)
INLINE_SYSCALL(close, 1, log_socket);
/* Try SOCK_STREAM connection to syslog */
DO_SOCKET(log_socket, AF_UNIX, SOCK_STREAM, 0);
if (log_socket != -1)
DO_CONNECT(connect_result, log_socket, &sock, sizeof(sock));
}
/* Build message. Messages are generated both in the old style and new style,
* so that log watchers that are configured for the old-style message continue
* to work.
*/
#define strconcat(str) \
{i=0; while ((str[i] != '\0') && ((i+plen)<(MESSAGE_BUFSIZ-1))) \
{\
message[plen+i]=str[i];\
i++;\
}\
plen+=i;}
/* R.Henderson post-gcc-4 style message */
plen = 0;
strconcat(msg_ssd);
if (__progname != (char *)0)
strconcat(__progname)
else
strconcat(msg_unknown);
strconcat(msg_terminated);
/* Write out error message to STDERR, to syslog if open */
INLINE_SYSCALL(write, 3, STDERR_FILENO, message, plen);
if (connect_result != -1)
INLINE_SYSCALL(write, 3, log_socket, message, plen);
/* Dr. Etoh pre-gcc-4 style message */
plen = 0;
if (__progname != (char *)0)
strconcat(__progname)
else
strconcat(msg_unknown);
strconcat(msg_ssa);
strconcat(msg_inf);
if (func != NULL)
strconcat(func)
else
strconcat(msg_unknown);
strconcat(msg_terminated);
/* Write out error message to STDERR, to syslog if open */
INLINE_SYSCALL(write, 3, STDERR_FILENO, message, plen);
if (connect_result != -1)
INLINE_SYSCALL(write, 3, log_socket, message, plen);
/* Direct reports to bugs.gentoo.org */
plen=0;
strconcat(msg_report);
message[plen++]='\0';
/* Write out error message to STDERR, to syslog if open */
INLINE_SYSCALL(write, 3, STDERR_FILENO, message, plen);
if (connect_result != -1)
INLINE_SYSCALL(write, 3, log_socket, message, plen);
if (log_socket != -1)
INLINE_SYSCALL(close, 1, log_socket);
/* Suicide */
pid = INLINE_SYSCALL(getpid, 0);
if (ENABLE_SSP_SMASH_DUMPS_CORE) {
static struct sigaction default_abort_act;
/* Remove any user-supplied handler for SIGABRT, before using it */
default_abort_act.sa_handler = SIG_DFL;
default_abort_act.sa_sigaction = NULL;
__sigfillset(&default_abort_act.sa_mask);
default_abort_act.sa_flags = 0;
if (DO_SIGACTION(SIGABRT, &default_abort_act, NULL) == 0)
INLINE_SYSCALL(kill, 2, pid, SIGABRT);
}
/* Note; actions cannot be added to SIGKILL */
INLINE_SYSCALL(kill, 2, pid, SIGKILL);
/* In case the kill didn't work, exit anyway
* The loop prevents gcc thinking this routine returns
*/
while (1)
INLINE_SYSCALL(exit, 0);
}
__attribute__ ((__noreturn__))
void __chk_fail(void)
{
__hardened_gentoo_chk_fail(NULL, 0);
}

View File

@ -0,0 +1,322 @@
/* Copyright (C) 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
/* Copyright (C) 2006-2013 Gentoo Foundation Inc.
* License terms as above.
*
* Hardened Gentoo SSP handler
*
* An SSP failure handler that does not use functions from the rest of
* glibc; it uses the INTERNAL_SYSCALL methods directly. This ensures
* no possibility of recursion into the handler.
*
* Direct all bug reports to http://bugs.gentoo.org/
*
* Re-written from the glibc-2.3 Hardened Gentoo SSP handler
* by Kevin F. Quinn - <kevquinn[@]gentoo.org>
*
* Fixed to support glibc-2.18 by Magnus Granberg - <zorry[@]gentoo.org>
*
* The following people contributed to the glibc-2.3 Hardened
* Gentoo SSP handler, from which this implementation draws much:
*
* 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>
* Mike Frysinger <vapier[@]gentoo.org>
*/
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sysdep-cancel.h>
#include <sys/syscall.h>
#include <kernel-features.h>
#include <alloca.h>
/* from sysdeps */
#include <socketcall.h>
/* for the stuff in bits/socket.h */
#include <sys/socket.h>
#include <sys/un.h>
/* Sanity check on SYSCALL macro names - force compilation
* failure if the names used here do not exist
*/
#if !defined __NR_socketcall && !defined __NR_socket
# error Cannot do syscall socket or socketcall
#endif
#if !defined __NR_socketcall && !defined __NR_connect
# error Cannot do syscall connect or socketcall
#endif
#ifndef __NR_write
# error Cannot do syscall write
#endif
#ifndef __NR_close
# error Cannot do syscall close
#endif
#ifndef __NR_getpid
# error Cannot do syscall getpid
#endif
#ifndef __NR_kill
# error Cannot do syscall kill
#endif
#ifndef __NR_exit
# error Cannot do syscall exit
#endif
#ifdef SSP_SMASH_DUMPS_CORE
# define ENABLE_SSP_SMASH_DUMPS_CORE 1
# if !defined _KERNEL_NSIG && !defined _NSIG
# error No _NSIG or _KERNEL_NSIG for rt_sigaction
# endif
# if !defined __NR_sigaction && !defined __NR_rt_sigaction
# error Cannot do syscall sigaction or rt_sigaction
# endif
/* Although rt_sigaction expects sizeof(sigset_t) - it expects the size
* of the _kernel_ sigset_t which is not the same as the user sigset_t.
* Most arches have this as _NSIG bits - mips has _KERNEL_NSIG bits for
* some reason.
*/
# ifdef _KERNEL_NSIG
# define _SSP_NSIG _KERNEL_NSIG
# else
# define _SSP_NSIG _NSIG
# endif
#else
# define _SSP_NSIG 0
# define ENABLE_SSP_SMASH_DUMPS_CORE 0
#endif
/* Define DO_SIGACTION - default to newer rt signal interface but
* fallback to old as needed.
*/
#ifdef __NR_rt_sigaction
# define DO_SIGACTION(signum, act, oldact) \
INLINE_SYSCALL(rt_sigaction, 4, signum, act, oldact, _SSP_NSIG/8)
#else
# define DO_SIGACTION(signum, act, oldact) \
INLINE_SYSCALL(sigaction, 3, signum, act, oldact)
#endif
/* Define DO_SOCKET/DO_CONNECT functions to deal with socketcall vs socket/connect */
#if defined(__NR_socket) && defined(__NR_connect)
# define USE_OLD_SOCKETCALL 0
#else
# define USE_OLD_SOCKETCALL 1
#endif
/* stub out the __NR_'s so we can let gcc optimize away dead code */
#ifndef __NR_socketcall
# define __NR_socketcall 0
#endif
#ifndef __NR_socket
# define __NR_socket 0
#endif
#ifndef __NR_connect
# define __NR_connect 0
#endif
#define DO_SOCKET(result, domain, type, protocol) \
do { \
if (USE_OLD_SOCKETCALL) { \
socketargs[0] = domain; \
socketargs[1] = type; \
socketargs[2] = protocol; \
socketargs[3] = 0; \
result = INLINE_SYSCALL(socketcall, 2, SOCKOP_socket, socketargs); \
} else \
result = INLINE_SYSCALL(socket, 3, domain, type, protocol); \
} while (0)
#define DO_CONNECT(result, sockfd, serv_addr, addrlen) \
do { \
if (USE_OLD_SOCKETCALL) { \
socketargs[0] = sockfd; \
socketargs[1] = (unsigned long int)serv_addr; \
socketargs[2] = addrlen; \
socketargs[3] = 0; \
result = INLINE_SYSCALL(socketcall, 2, SOCKOP_connect, socketargs); \
} else \
result = INLINE_SYSCALL(connect, 3, sockfd, serv_addr, addrlen); \
} while (0)
#ifndef _PATH_LOG
# define _PATH_LOG "/dev/log"
#endif
static const char path_log[] = _PATH_LOG;
/* For building glibc with SSP switched on, define __progname to a
* constant if building for the run-time loader, to avoid pulling
* in more of libc.so into ld.so
*/
#ifdef IS_IN_rtld
static char *__progname = "<rtld>";
#else
extern char *__progname;
#endif
/* Common handler code, used by stack_chk_fail and __stack_smash_handler
* Inlined to ensure no self-references to the handler within itself.
* Data static to avoid putting more than necessary on the stack,
* to aid core debugging.
*/
__attribute__ ((__noreturn__ , __always_inline__))
static inline void
__hardened_gentoo_stack_chk_fail(char func[], int damaged)
{
#define MESSAGE_BUFSIZ 256
static pid_t pid;
static int plen, i;
static char message[MESSAGE_BUFSIZ];
static const char msg_ssa[] = ": stack smashing attack";
static const char msg_inf[] = " in function ";
static const char msg_ssd[] = "*** stack smashing detected ***: ";
static const char msg_terminated[] = " - terminated\n";
static const char msg_report[] = "Report to http://bugs.gentoo.org/\n";
static const char msg_unknown[] = "<unknown>";
static int log_socket, connect_result;
static struct sockaddr_un sock;
static unsigned long int socketargs[4];
/* Build socket address
*/
sock.sun_family = AF_UNIX;
i = 0;
while ((path_log[i] != '\0') && (i<(sizeof(sock.sun_path)-1))) {
sock.sun_path[i] = path_log[i];
i++;
}
sock.sun_path[i] = '\0';
/* Try SOCK_DGRAM connection to syslog */
connect_result = -1;
DO_SOCKET(log_socket, AF_UNIX, SOCK_DGRAM, 0);
if (log_socket != -1)
DO_CONNECT(connect_result, log_socket, &sock, sizeof(sock));
if (connect_result == -1) {
if (log_socket != -1)
INLINE_SYSCALL(close, 1, log_socket);
/* Try SOCK_STREAM connection to syslog */
DO_SOCKET(log_socket, AF_UNIX, SOCK_STREAM, 0);
if (log_socket != -1)
DO_CONNECT(connect_result, log_socket, &sock, sizeof(sock));
}
/* Build message. Messages are generated both in the old style and new style,
* so that log watchers that are configured for the old-style message continue
* to work.
*/
#define strconcat(str) \
{i=0; while ((str[i] != '\0') && ((i+plen)<(MESSAGE_BUFSIZ-1))) \
{\
message[plen+i]=str[i];\
i++;\
}\
plen+=i;}
/* R.Henderson post-gcc-4 style message */
plen = 0;
strconcat(msg_ssd);
if (__progname != (char *)0)
strconcat(__progname)
else
strconcat(msg_unknown);
strconcat(msg_terminated);
/* Write out error message to STDERR, to syslog if open */
INLINE_SYSCALL(write, 3, STDERR_FILENO, message, plen);
if (connect_result != -1)
INLINE_SYSCALL(write, 3, log_socket, message, plen);
/* Dr. Etoh pre-gcc-4 style message */
plen = 0;
if (__progname != (char *)0)
strconcat(__progname)
else
strconcat(msg_unknown);
strconcat(msg_ssa);
strconcat(msg_inf);
if (func != NULL)
strconcat(func)
else
strconcat(msg_unknown);
strconcat(msg_terminated);
/* Write out error message to STDERR, to syslog if open */
INLINE_SYSCALL(write, 3, STDERR_FILENO, message, plen);
if (connect_result != -1)
INLINE_SYSCALL(write, 3, log_socket, message, plen);
/* Direct reports to bugs.gentoo.org */
plen=0;
strconcat(msg_report);
message[plen++]='\0';
/* Write out error message to STDERR, to syslog if open */
INLINE_SYSCALL(write, 3, STDERR_FILENO, message, plen);
if (connect_result != -1)
INLINE_SYSCALL(write, 3, log_socket, message, plen);
if (log_socket != -1)
INLINE_SYSCALL(close, 1, log_socket);
/* Suicide */
pid = INLINE_SYSCALL(getpid, 0);
if (ENABLE_SSP_SMASH_DUMPS_CORE) {
static struct sigaction default_abort_act;
/* Remove any user-supplied handler for SIGABRT, before using it */
default_abort_act.sa_handler = SIG_DFL;
default_abort_act.sa_sigaction = NULL;
__sigfillset(&default_abort_act.sa_mask);
default_abort_act.sa_flags = 0;
if (DO_SIGACTION(SIGABRT, &default_abort_act, NULL) == 0)
INLINE_SYSCALL(kill, 2, pid, SIGABRT);
}
/* Note; actions cannot be added to SIGKILL */
INLINE_SYSCALL(kill, 2, pid, SIGKILL);
/* In case the kill didn't work, exit anyway
* The loop prevents gcc thinking this routine returns
*/
while (1)
INLINE_SYSCALL(exit, 0);
}
__attribute__ ((__noreturn__))
void __stack_chk_fail(void)
{
__hardened_gentoo_stack_chk_fail(NULL, 0);
}
#ifdef ENABLE_OLD_SSP_COMPAT
__attribute__ ((__noreturn__))
void __stack_smash_handler(char func[], int damaged)
{
__hardened_gentoo_stack_chk_fail(func, damaged);
}
#endif

View File

@ -0,0 +1,277 @@
When building glibc PIE (which is not something upstream support),
several modifications are necessary to the glibc build process.
First, any syscalls in PIEs must be of the PIC variant, otherwise
textrels ensue. Then, any syscalls made before the initialisation
of the TLS will fail on i386, as the sysenter variant on i386 uses
the TLS, giving rise to a chicken-and-egg situation. This patch
defines a PIC syscall variant that doesn't use sysenter, even when the sysenter
version is normally used, and uses the non-sysenter version for the brk
syscall that is performed by the TLS initialisation. Further, the TLS
initialisation is moved in this case prior to the initialisation of
dl_osversion, as that requires further syscalls.
csu/libc-start.c: Move initial TLS initialization to before the
initialisation of dl_osversion, when INTERNAL_SYSCALL_NOSYSENTER is defined
csu/libc-tls.c: Use the no-sysenter version of sbrk when
INTERNAL_SYSCALL_NOSYSENTER is defined.
misc/sbrk.c: Define a no-sysenter version of sbrk, using the no-sysenter
version of brk - if INTERNAL_SYSCALL_NOSYSENTER is defined.
misc/brk.c: Define a no-sysenter version of brk if
INTERNAL_SYSCALL_NOSYSENTER is defined.
sysdeps/unix/sysv/linux/i386/sysdep.h: Define INTERNAL_SYSCALL_NOSYSENTER
Make INTERNAL_SYSCALL always use the PIC variant, even if not SHARED.
Patch by Kevin F. Quinn <kevquinn@gentoo.org>
Fixed for 2.10 by Magnus Granberg <zorry@ume.nu>
Fixed for 2.18 by Magnus Granberg <zorry@gentoo.org>
--- csu/libc-start.c
+++ csu/libc-start.c
@@ -28,6 +28,7 @@
extern int __libc_multiple_libcs;
#include <tls.h>
+#include <sysdep.h>
#ifndef SHARED
# include <dl-osinfo.h>
extern void __pthread_initialize_minimal (void);
@@ -170,7 +170,11 @@ LIBC_START_MAIN (int (*main) (int, char
GL(dl_phnum) = __ehdr_start.e_phnum;
}
}
-
+# ifdef INTERNAL_SYSCALL_NOSYSENTER
+ /* Do the initial TLS initialization before _dl_osversion,
+ since the latter uses the uname syscall. */
+ __pthread_initialize_minimal ();
+# endif
# ifdef DL_SYSDEP_OSCHECK
if (!__libc_multiple_libcs)
{
@@ -138,10 +144,12 @@
}
# endif
+# ifndef INTERNAL_SYSCALL_NOSYSENTER
/* Initialize the thread library at least a bit since the libgcc
functions are using thread functions if these are available and
we need to setup errno. */
__pthread_initialize_minimal ();
+# endif
/* Set up the stack checker's canary. */
uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard ();
--- csu/libc-tls.c
+++ csu/libc-tls.c
@@ -22,14 +22,17 @@
#include <unistd.h>
#include <stdio.h>
#include <sys/param.h>
-
+#include <sysdep.h>
#ifdef SHARED
#error makefile bug, this file is for static only
#endif
-dtv_t _dl_static_dtv[2 + TLS_SLOTINFO_SURPLUS];
+#ifdef INTERNAL_SYSCALL_NOSYSENTER
+extern void *__sbrk_nosysenter (intptr_t __delta);
+#endif
+dtv_t _dl_static_dtv[2 + TLS_SLOTINFO_SURPLUS];
static struct
{
@@ -139,14 +142,26 @@ __libc_setup_tls (size_t tcbsize, size_t
The initialized value of _dl_tls_static_size is provided by dl-open.c
to request some surplus that permits dynamic loading of modules with
- IE-model TLS. */
+ IE-model TLS.
+
+ Where the normal sbrk would use a syscall that needs the TLS (i386)
+ use the special non-sysenter version instead. */
#if TLS_TCB_AT_TP
tcb_offset = roundup (memsz + GL(dl_tls_static_size), tcbalign);
+# ifdef INTERNAL_SYSCALL_NOSYSENTER
+ tlsblock = __sbrk_nosysenter (tcb_offset + tcbsize + max_align);
+# else
tlsblock = __sbrk (tcb_offset + tcbsize + max_align);
+#endif
#elif TLS_DTV_AT_TP
tcb_offset = roundup (tcbsize, align ?: 1);
+# ifdef INTERNAL_SYSCALL_NOSYSENTER
+ tlsblock = __sbrk_nosysenter (tcb_offset + memsz + max_align
+ + TLS_PRE_TCB_SIZE + GL(dl_tls_static_size));
+# else
tlsblock = __sbrk (tcb_offset + memsz + max_align
+ TLS_PRE_TCB_SIZE + GL(dl_tls_static_size));
+#endif
tlsblock += TLS_PRE_TCB_SIZE;
#else
/* In case a model with a different layout for the TCB and DTV
--- misc/sbrk.c
+++ misc/sbrk.c
@@ -18,6 +18,7 @@
#include <errno.h>
#include <stdint.h>
#include <unistd.h>
+#include <sysdep.h>
/* Defined in brk.c. */
extern void *__curbrk;
@@ -29,6 +30,35 @@
/* Extend the process's data space by INCREMENT.
If INCREMENT is negative, shrink data space by - INCREMENT.
Return start of new space allocated, or -1 for errors. */
+#ifdef INTERNAL_SYSCALL_NOSYSENTER
+/* This version is used by csu/libc-tls.c whem initialising the TLS
+ if the SYSENTER version requires the TLS (which it does on i386).
+ Obviously using the TLS before it is initialised is broken. */
+extern int __brk_nosysenter (void *addr);
+void *
+__sbrk_nosysenter (intptr_t increment)
+{
+ void *oldbrk;
+
+ /* If this is not part of the dynamic library or the library is used
+ via dynamic loading in a statically linked program update
+ __curbrk from the kernel's brk value. That way two separate
+ instances of __brk and __sbrk can share the heap, returning
+ interleaved pieces of it. */
+ if (__curbrk == NULL || __libc_multiple_libcs)
+ if (__brk_nosysenter (0) < 0) /* Initialize the break. */
+ return (void *) -1;
+
+ if (increment == 0)
+ return __curbrk;
+
+ oldbrk = __curbrk;
+ if (__brk_nosysenter (oldbrk + increment) < 0)
+ return (void *) -1;
+
+ return oldbrk;
+}
+#endif
void *
__sbrk (intptr_t increment)
{
--- sysdeps/unix/sysv/linux/i386/brk.c
+++ sysdeps/unix/sysv/linux/i386/brk.c
@@ -31,6 +31,29 @@
linker. */
weak_alias (__curbrk, ___brk_addr)
+#ifdef INTERNAL_SYSCALL_NOSYSENTER
+/* This version is used by csu/libc-tls.c whem initialising the TLS
+ * if the SYSENTER version requires the TLS (which it does on i386).
+ * Obviously using the TLS before it is initialised is broken. */
+int
+__brk_nosysenter (void *addr)
+{
+ void * newbrk;
+
+ INTERNAL_SYSCALL_DECL (err);
+ newbrk = (void *) INTERNAL_SYSCALL_NOSYSENTER (brk, err, 1, addr);
+
+ __curbrk = newbrk;
+
+ if (newbrk < addr)
+ {
+ __set_errno (ENOMEM);
+ return -1;
+ }
+
+ return 0;
+}
+#endif
int
__brk (void *addr)
{
--- sysdeps/unix/sysv/linux/i386/sysdep.h
+++ sysdeps/unix/sysv/linux/i386/sysdep.h
@@ -187,7 +187,7 @@
/* The original calling convention for system calls on Linux/i386 is
to use int $0x80. */
#ifdef I386_USE_SYSENTER
-# ifdef SHARED
+# if defined SHARED || defined __PIC__
# define ENTER_KERNEL call *%gs:SYSINFO_OFFSET
# else
# define ENTER_KERNEL call *_dl_sysinfo
@@ -358,7 +358,7 @@
possible to use more than four parameters. */
#undef INTERNAL_SYSCALL
#ifdef I386_USE_SYSENTER
-# ifdef SHARED
+# if defined SHARED || defined __PIC__
# define INTERNAL_SYSCALL(name, err, nr, args...) \
({ \
register unsigned int resultvar; \
@@ -384,6 +384,18 @@
: "0" (name), "i" (offsetof (tcbhead_t, sysinfo)) \
ASMFMT_##nr(args) : "memory", "cc"); \
(int) resultvar; })
+# define INTERNAL_SYSCALL_NOSYSENTER(name, err, nr, args...) \
+ ({ \
+ register unsigned int resultvar; \
+ EXTRAVAR_##nr \
+ asm volatile ( \
+ LOADARGS_NOSYSENTER_##nr \
+ "movl %1, %%eax\n\t" \
+ "int $0x80\n\t" \
+ RESTOREARGS_NOSYSENTER_##nr \
+ : "=a" (resultvar) \
+ : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc"); \
+ (int) resultvar; })
# else
# define INTERNAL_SYSCALL(name, err, nr, args...) \
({ \
@@ -447,12 +459,20 @@
#define LOADARGS_0
#ifdef __PIC__
-# if defined I386_USE_SYSENTER && defined SHARED
+# if defined I386_USE_SYSENTER && ( defined SHARED || defined __PIC__ )
# define LOADARGS_1 \
"bpushl .L__X'%k3, %k3\n\t"
# define LOADARGS_5 \
"movl %%ebx, %4\n\t" \
"movl %3, %%ebx\n\t"
+# define LOADARGS_NOSYSENTER_1 \
+ "bpushl .L__X'%k2, %k2\n\t"
+# define LOADARGS_NOSYSENTER_2 LOADARGS_NOSYSENTER_1
+# define LOADARGS_NOSYSENTER_3 LOADARGS_3
+# define LOADARGS_NOSYSENTER_4 LOADARGS_3
+# define LOADARGS_NOSYSENTER_5 \
+ "movl %%ebx, %3\n\t" \
+ "movl %2, %%ebx\n\t"
# else
# define LOADARGS_1 \
"bpushl .L__X'%k2, %k2\n\t"
@@ -474,11 +495,18 @@
#define RESTOREARGS_0
#ifdef __PIC__
-# if defined I386_USE_SYSENTER && defined SHARED
+# if defined I386_USE_SYSENTER && ( defined SHARED || defined __PIC__ )
# define RESTOREARGS_1 \
"bpopl .L__X'%k3, %k3\n\t"
# define RESTOREARGS_5 \
"movl %4, %%ebx"
+# define RESTOREARGS_NOSYSENTER_1 \
+ "bpopl .L__X'%k2, %k2\n\t"
+# define RESTOREARGS_NOSYSENTER_2 RESTOREARGS_NOSYSENTER_1
+# define RESTOREARGS_NOSYSENTER_3 RESTOREARGS_3
+# define RESTOREARGS_NOSYSENTER_4 RESTOREARGS_3
+# define RESTOREARGS_NOSYSENTER_5 \
+ "movl %3, %%ebx"
# else
# define RESTOREARGS_1 \
"bpopl .L__X'%k2, %k2\n\t"

View File

@ -0,0 +1,68 @@
#! /bin/sh -e
# DP: Description: Fix localedef segfault when run under exec-shield,
# PaX or similar. (#231438, #198099)
# DP: Dpatch Author: James Troup <james@nocrew.org>
# DP: Patch Author: (probably) Jakub Jelinek <jakub@redhat.com>
# DP: Upstream status: Unknown
# DP: Status Details: Unknown
# DP: Date: 2004-03-16
if [ $# -ne 2 ]; then
echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
exit 1
fi
case "$1" in
-patch) patch -d "$2" -f --no-backup-if-mismatch -p1 < $0;;
-unpatch) patch -d "$2" -f --no-backup-if-mismatch -R -p1 < $0;;
*)
echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
exit 1
esac
exit 0
--- glibc-2.3.3-net/locale/programs/3level.h 16 Jun 2003 07:19:09 -0000 1.1.1.5
+++ glibc-2.3.3-redhat/locale/programs/3level.h 16 Jun 2003 09:32:40 -0000 1.4
@@ -204,6 +204,42 @@ CONCAT(TABLE,_iterate) (struct TABLE *t,
}
}
}
+
+/* GCC ATM seems to do a poor job with pointers to nested functions passed
+ to inlined functions. Help it a little bit with this hack. */
+#define wchead_table_iterate(tp, fn) \
+do \
+ { \
+ struct wchead_table *t = (tp); \
+ uint32_t index1; \
+ for (index1 = 0; index1 < t->level1_size; index1++) \
+ { \
+ uint32_t lookup1 = t->level1[index1]; \
+ if (lookup1 != ((uint32_t) ~0)) \
+ { \
+ uint32_t lookup1_shifted = lookup1 << t->q; \
+ uint32_t index2; \
+ for (index2 = 0; index2 < (1 << t->q); index2++) \
+ { \
+ uint32_t lookup2 = t->level2[index2 + lookup1_shifted]; \
+ if (lookup2 != ((uint32_t) ~0)) \
+ { \
+ uint32_t lookup2_shifted = lookup2 << t->p; \
+ uint32_t index3; \
+ for (index3 = 0; index3 < (1 << t->p); index3++) \
+ { \
+ struct element_t *lookup3 \
+ = t->level3[index3 + lookup2_shifted]; \
+ if (lookup3 != NULL) \
+ fn ((((index1 << t->q) + index2) << t->p) + index3, \
+ lookup3); \
+ } \
+ } \
+ } \
+ } \
+ } \
+ } while (0)
+
#endif
#ifndef NO_FINALIZE

View File

@ -0,0 +1,311 @@
/* Copyright (C) 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
/* Copyright (C) 2006 Gentoo Foundation Inc.
* License terms as above.
*
* Hardened Gentoo SSP handler
*
* An SSP failure handler that does not use functions from the rest of
* glibc; it uses the INTERNAL_SYSCALL methods directly. This ensures
* no possibility of recursion into the handler.
*
* Direct all bug reports to http://bugs.gentoo.org/
*
* Re-written from the glibc-2.3 Hardened Gentoo SSP handler
* by Kevin F. Quinn - <kevquinn[@]gentoo.org>
*
* The following people contributed to the glibc-2.3 Hardened
* Gentoo SSP handler, from which this implementation draws much:
*
* 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>
* Mike Frysinger <vapier[@]gentoo.org>
*/
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sysdep-cancel.h>
#include <sys/syscall.h>
#include <bp-checks.h>
#include <kernel-features.h>
#include <alloca.h>
/* from sysdeps */
#include <socketcall.h>
/* for the stuff in bits/socket.h */
#include <sys/socket.h>
#include <sys/un.h>
/* Sanity check on SYSCALL macro names - force compilation
* failure if the names used here do not exist
*/
#if !defined __NR_socketcall && !defined __NR_socket
# error Cannot do syscall socket or socketcall
#endif
#if !defined __NR_socketcall && !defined __NR_connect
# error Cannot do syscall connect or socketcall
#endif
#ifndef __NR_write
# error Cannot do syscall write
#endif
#ifndef __NR_close
# error Cannot do syscall close
#endif
#ifndef __NR_getpid
# error Cannot do syscall getpid
#endif
#ifndef __NR_kill
# error Cannot do syscall kill
#endif
#ifndef __NR_exit
# error Cannot do syscall exit
#endif
#ifdef SSP_SMASH_DUMPS_CORE
# if !defined _KERNEL_NSIG && !defined _NSIG
# error No _NSIG or _KERNEL_NSIG for rt_sigaction
# endif
# if !defined __NR_sigation && !defined __NR_rt_sigaction
# error Cannot do syscall sigaction or rt_sigaction
# endif
#endif
/* Define DO_SOCKET/DO_CONNECT macros to deal with socketcall vs socket/connect */
#ifdef __NR_socketcall
# define DO_SOCKET(result,domain,type,protocol) \
{socketargs[0] = domain; \
socketargs[1] = type; \
socketargs[2] = protocol; \
socketargs[3] = 0; \
result = INLINE_SYSCALL(socketcall,2,SOCKOP_socket,socketargs);}
# define DO_CONNECT(result,sockfd,serv_addr,addrlen) \
{socketargs[0] = sockfd; \
socketargs[1] = (unsigned long int)serv_addr; \
socketargs[2] = addrlen; \
socketargs[3] = 0; \
result = INLINE_SYSCALL(socketcall,2,SOCKOP_connect,socketargs);}
#else
# define DO_SOCKET(result,domain,type,protocol) \
{result = INLINE_SYSCALL(socket,3,domain,type,protocol);}
# define DO_CONNECT(result,sockfd,serv_addr,addrlen) \
{result = INLINE_SYSCALL(connect,3,sockfd,serv_addr,addrlen);}
#endif
/* __NR_socketcall */
#ifndef _PATH_LOG
# define _PATH_LOG "/dev/log"
#endif
static const char path_log[]=_PATH_LOG;
/* For building glibc with SSP switched on, define __progname to a
* constant if building for the run-time loader, to avoid pulling
* in more of libc.so into ld.so
*/
#ifdef IS_IN_rtld
static char *__progname = "<rtld>";
#else
extern char *__progname;
#endif
/* Common handler code, used by stack_chk_fail and __stack_smash_handler
* Inlined to ensure no self-references to the handler within itself.
* Data static to avoid putting more than necessary on the stack,
* to aid core debugging.
*/
static inline void
__attribute__ ((__noreturn__ , __always_inline__))
__hardened_gentoo_stack_chk_fail (char func[], int damaged)
{
#define MESSAGE_BUFSIZ 256
static pid_t pid;
static int plen, i;
static char message[MESSAGE_BUFSIZ];
static const char msg_ssa[]=": stack smashing attack";
static const char msg_inf[]=" in function ";
static const char msg_ssd[]="*** stack smashing detected ***: ";
static const char msg_terminated[]=" - terminated\n";
static const char msg_report[]="Report to http://bugs.gentoo.org/\n";
static const char msg_unknown[]="<unknown>";
#ifdef SSP_SMASH_DUMPS_CORE
static struct sigaction default_abort_act;
#endif
static int log_socket, connect_result;
static struct sockaddr_un sock;
#ifdef __NR_socketcall
static unsigned long int socketargs[4];
#endif
/* Build socket address
*/
sock.sun_family = AF_UNIX;
i=0;
while ((path_log[i] != '\0') && (i<(sizeof(sock.sun_path)-1)))
{
sock.sun_path[i]=path_log[i];
i++;
}
sock.sun_path[i]='\0';
/* Try SOCK_DGRAM connection to syslog */
connect_result=-1;
DO_SOCKET(log_socket,AF_UNIX,SOCK_DGRAM,0);
if (log_socket != -1)
DO_CONNECT(connect_result,log_socket,(&sock),(sizeof(sock)));
if (connect_result == -1)
{
if (log_socket != -1)
INLINE_SYSCALL(close,1,log_socket);
/* Try SOCK_STREAM connection to syslog */
DO_SOCKET(log_socket,AF_UNIX,SOCK_STREAM,0);
if (log_socket != -1)
DO_CONNECT(connect_result,log_socket,(&sock),(sizeof(sock)));
}
/* Build message. Messages are generated both in the old style and new style,
* so that log watchers that are configured for the old-style message continue
* to work.
*/
#define strconcat(str) \
{i=0; while ((str[i] != '\0') && ((i+plen)<(MESSAGE_BUFSIZ-1))) \
{\
message[plen+i]=str[i];\
i++;\
}\
plen+=i;}
/* R.Henderson post-gcc-4 style message */
plen=0;
strconcat(msg_ssd);
if (__progname != (char *)0)
strconcat(__progname)
else
strconcat(msg_unknown);
strconcat(msg_terminated);
/* Write out error message to STDERR, to syslog if open */
INLINE_SYSCALL(write,3,STDERR_FILENO,message,plen);
if (connect_result != -1)
INLINE_SYSCALL(write,3,log_socket,message,plen);
/* Dr. Etoh pre-gcc-4 style message */
plen=0;
if (__progname != (char *)0)
strconcat(__progname)
else
strconcat(msg_unknown);
strconcat(msg_ssa);
strconcat(msg_inf);
if (func!=NULL)
strconcat(func)
else
strconcat(msg_unknown);
strconcat(msg_terminated);
/* Write out error message to STDERR, to syslog if open */
INLINE_SYSCALL(write,3,STDERR_FILENO,message,plen);
if (connect_result != -1)
INLINE_SYSCALL(write,3,log_socket,message,plen);
/* Direct reports to bugs.gentoo.org */
plen=0;
strconcat(msg_report);
message[plen++]='\0';
/* Write out error message to STDERR, to syslog if open */
INLINE_SYSCALL(write,3,STDERR_FILENO,message,plen);
if (connect_result != -1)
INLINE_SYSCALL(write,3,log_socket,message,plen);
if (log_socket != -1)
INLINE_SYSCALL(close,1,log_socket);
/* Suicide */
pid=INLINE_SYSCALL(getpid,0);
#ifdef SSP_SMASH_DUMPS_CORE
/* Remove any user-supplied handler for SIGABRT, before using it */
default_abort_act.sa_handler = SIG_DFL;
default_abort_act.sa_sigaction = NULL;
__sigfillset(&default_abort_act.sa_mask);
default_abort_act.sa_flags = 0;
/* sigaction doesn't exist on amd64; however rt_sigaction seems to
* exist everywhere. rt_sigaction has an extra parameter - the
* size of sigset_t.
*/
# ifdef __NR_sigation
if (INLINE_SYSCALL(sigaction,3,SIGABRT,&default_abort_act,NULL) == 0)
# else
/* Although rt_sigaction expects sizeof(sigset_t) - it expects the size
* of the _kernel_ sigset_t which is not the same as the user sigset_t.
* Most arches have this as _NSIG bits - mips has _KERNEL_NSIG bits for
* some reason.
*/
# ifdef _KERNEL_NSIG
if (INLINE_SYSCALL(rt_sigaction,4,SIGABRT,&default_abort_act,NULL,_KERNEL_NSIG/8) == 0)
# else
if (INLINE_SYSCALL(rt_sigaction,4,SIGABRT,&default_abort_act,NULL,_NSIG/8) == 0)
# endif
# endif
INLINE_SYSCALL(kill,2,pid,SIGABRT);
#endif
/* Note; actions cannot be added to SIGKILL */
INLINE_SYSCALL(kill,2,pid,SIGKILL);
/* In case the kill didn't work, exit anyway
* The loop prevents gcc thinking this routine returns
*/
while (1) INLINE_SYSCALL(exit,0);
}
void
__attribute__ ((__noreturn__))
__stack_chk_fail (void)
{
__hardened_gentoo_stack_chk_fail(NULL,0);
}
#ifdef ENABLE_OLD_SSP_COMPAT
void
__attribute__ ((__noreturn__))
__stack_smash_handler(char func[], int damaged)
{
__hardened_gentoo_stack_chk_fail(func,damaged);
}
#endif

View File

@ -0,0 +1,29 @@
Prevent default-fPIE from confusing configure into thinking
PIC code is default. This causes glibc to build both PIC and
non-PIC code as normal, which on the hardened compiler generates
PIC and PIE.
Patch by Kevin F. Quinn <kevquinn@gentoo.org>
--- configure.in
+++ configure.in
@@ -2145,7 +2145,7 @@
# error PIC is default.
#endif
EOF
-if eval "${CC-cc} -S conftest.c 2>&AS_MESSAGE_LOG_FD 1>&AS_MESSAGE_LOG_FD"; then
+if eval "${CC-cc} -fno-PIE -S conftest.c 2>&AS_MESSAGE_LOG_FD 1>&AS_MESSAGE_LOG_FD"; then
pic_default=no
fi
rm -f conftest.*])
--- configure
+++ configure
@@ -7698,7 +7698,7 @@
# error PIC is default.
#endif
EOF
-if eval "${CC-cc} -S conftest.c 2>&5 1>&5"; then
+if eval "${CC-cc} -fno-PIE -S conftest.c 2>&5 1>&5"; then
pic_default=no
fi
rm -f conftest.*

View File

@ -0,0 +1,283 @@
When building glibc PIE (which is not something upstream support),
several modifications are necessary to the glibc build process.
First, any syscalls in PIEs must be of the PIC variant, otherwise
textrels ensue. Then, any syscalls made before the initialisation
of the TLS will fail on i386, as the sysenter variant on i386 uses
the TLS, giving rise to a chicken-and-egg situation. This patch
defines a PIC syscall variant that doesn't use sysenter, even when the sysenter
version is normally used, and uses the non-sysenter version for the brk
syscall that is performed by the TLS initialisation. Further, the TLS
initialisation is moved in this case prior to the initialisation of
dl_osversion, as that requires further syscalls.
csu/libc-start.c: Move initial TLS initialization to before the
initialisation of dl_osversion, when INTERNAL_SYSCALL_NOSYSENTER is defined
csu/libc-tls.c: Use the no-sysenter version of sbrk when
INTERNAL_SYSCALL_NOSYSENTER is defined.
misc/sbrk.c: Define a no-sysenter version of sbrk, using the no-sysenter
version of brk - if INTERNAL_SYSCALL_NOSYSENTER is defined.
misc/brk.c: Define a no-sysenter version of brk if
INTERNAL_SYSCALL_NOSYSENTER is defined.
sysdeps/unix/sysv/linux/i386/sysdep.h: Define INTERNAL_SYSCALL_NOSYSENTER
Make INTERNAL_SYSCALL always use the PIC variant, even if not SHARED.
Patch by Kevin F. Quinn <kevquinn@gentoo.org>
--- csu/libc-start.c.orig 2007-01-21 11:51:06.000000000 +0100
+++ csu/libc-start.c 2007-01-21 11:55:57.000000000 +0100
@@ -28,6 +28,7 @@
extern int __libc_multiple_libcs;
#include <tls.h>
+#include <sysdep.h>
#ifndef SHARED
# include <dl-osinfo.h>
extern void __pthread_initialize_minimal (void)
@@ -133,6 +134,14 @@
# endif
_dl_aux_init (auxvec);
# endif
+# ifdef INTERNAL_SYSCALL_NOSYSENTER
+ /* Do the initial TLS initialization before _dl_osversion,
+ since the latter uses the uname syscall. */
+# if !(USE_TLS - 0) && !defined NONTLS_INIT_TP
+ if (__pthread_initialize_minimal)
+# endif
+ __pthread_initialize_minimal ();
+# endif
# ifdef DL_SYSDEP_OSCHECK
if (!__libc_multiple_libcs)
{
@@ -142,15 +151,17 @@
}
# endif
+# ifndef INTERNAL_SYSCALL_NOSYSENTER
/* Initialize the thread library at least a bit since the libgcc
functions are using thread functions if these are available and
we need to setup errno. If there is no thread library and we
handle TLS the function is defined in the libc to initialized the
TLS handling. */
-# if !(USE_TLS - 0) && !defined NONTLS_INIT_TP
+# if !(USE_TLS - 0) && !defined NONTLS_INIT_TP
if (__pthread_initialize_minimal)
-# endif
+# endif
__pthread_initialize_minimal ();
+# endif
#endif
# ifndef SHARED
--- csu/libc-tls.c.orig 2007-01-21 11:37:02.000000000 +0100
+++ csu/libc-tls.c 2007-01-21 12:09:33.000000000 +0100
@@ -23,6 +23,7 @@
#include <unistd.h>
#include <stdio.h>
#include <sys/param.h>
+#include <sysdep.h>
#ifdef SHARED
@@ -30,6 +31,9 @@
#endif
#ifdef USE_TLS
+# ifdef INTERNAL_SYSCALL_NOSYSENTER
+extern void *__sbrk_nosysenter (intptr_t __delta);
+# endif
extern ElfW(Phdr) *_dl_phdr;
extern size_t _dl_phnum;
@@ -142,14 +146,26 @@
The initialized value of _dl_tls_static_size is provided by dl-open.c
to request some surplus that permits dynamic loading of modules with
- IE-model TLS. */
+ IE-model TLS.
+
+ Where the normal sbrk would use a syscall that needs the TLS (i386)
+ use the special non-sysenter version instead. */
# if TLS_TCB_AT_TP
tcb_offset = roundup (memsz + GL(dl_tls_static_size), tcbalign);
+# ifdef INTERNAL_SYSCALL_NOSYSENTER
+ tlsblock = __sbrk_nosysenter (tcb_offset + tcbsize + max_align);
+# else
tlsblock = __sbrk (tcb_offset + tcbsize + max_align);
+# endif
# elif TLS_DTV_AT_TP
tcb_offset = roundup (tcbsize, align ?: 1);
+# ifdef INTERNAL_SYSCALL_NOSYSENTER
+ tlsblock = __sbrk_nosysenter (tcb_offset + memsz + max_align
+ + TLS_PRE_TCB_SIZE + GL(dl_tls_static_size));
+# else
tlsblock = __sbrk (tcb_offset + memsz + max_align
+ TLS_PRE_TCB_SIZE + GL(dl_tls_static_size));
+# endif
tlsblock += TLS_PRE_TCB_SIZE;
# else
/* In case a model with a different layout for the TCB and DTV
--- misc/sbrk.c.orig 2007-01-21 11:38:27.000000000 +0100
+++ misc/sbrk.c 2007-01-21 12:07:29.000000000 +0100
@@ -18,6 +18,7 @@
#include <unistd.h>
#include <errno.h>
+#include <sysdep.h>
/* Defined in brk.c. */
extern void *__curbrk;
@@ -29,6 +30,35 @@
/* Extend the process's data space by INCREMENT.
If INCREMENT is negative, shrink data space by - INCREMENT.
Return start of new space allocated, or -1 for errors. */
+#ifdef INTERNAL_SYSCALL_NOSYSENTER
+/* This version is used by csu/libc-tls.c whem initialising the TLS
+ if the SYSENTER version requires the TLS (which it does on i386).
+ Obviously using the TLS before it is initialised is broken. */
+extern int __brk_nosysenter (void *addr);
+void *
+__sbrk_nosysenter (intptr_t increment)
+{
+ void *oldbrk;
+
+ /* If this is not part of the dynamic library or the library is used
+ via dynamic loading in a statically linked program update
+ __curbrk from the kernel's brk value. That way two separate
+ instances of __brk and __sbrk can share the heap, returning
+ interleaved pieces of it. */
+ if (__curbrk == NULL || __libc_multiple_libcs)
+ if (__brk_nosysenter (0) < 0) /* Initialize the break. */
+ return (void *) -1;
+
+ if (increment == 0)
+ return __curbrk;
+
+ oldbrk = __curbrk;
+ if (__brk_nosysenter (oldbrk + increment) < 0)
+ return (void *) -1;
+
+ return oldbrk;
+}
+#endif
void *
__sbrk (intptr_t increment)
{
--- sysdeps/unix/sysv/linux/i386/brk.c.orig 2007-01-21 11:39:16.000000000 +0100
+++ sysdeps/unix/sysv/linux/i386/brk.c 2007-01-21 11:44:01.000000000 +0100
@@ -31,6 +31,30 @@
linker. */
weak_alias (__curbrk, ___brk_addr)
+#ifdef INTERNAL_SYSCALL_NOSYSENTER
+/* This version is used by csu/libc-tls.c whem initialising the TLS
+ * if the SYSENTER version requires the TLS (which it does on i386).
+ * Obviously using the TLS before it is initialised is broken. */
+int
+__brk_nosysenter (void *addr)
+{
+ void *__unbounded newbrk;
+
+ INTERNAL_SYSCALL_DECL (err);
+ newbrk = (void *__unbounded) INTERNAL_SYSCALL_NOSYSENTER (brk, err, 1,
+ __ptrvalue (addr));
+
+ __curbrk = newbrk;
+
+ if (newbrk < addr)
+ {
+ __set_errno (ENOMEM);
+ return -1;
+ }
+
+ return 0;
+}
+#endif
int
__brk (void *addr)
{
--- sysdeps/unix/sysv/linux/i386/sysdep.h.orig 2007-01-21 13:08:00.000000000 +0100
+++ sysdeps/unix/sysv/linux/i386/sysdep.h 2007-01-21 13:19:10.000000000 +0100
@@ -187,7 +187,7 @@
/* The original calling convention for system calls on Linux/i386 is
to use int $0x80. */
#ifdef I386_USE_SYSENTER
-# ifdef SHARED
+# if defined SHARED || defined __PIC__
# define ENTER_KERNEL call *%gs:SYSINFO_OFFSET
# else
# define ENTER_KERNEL call *_dl_sysinfo
@@ -358,7 +358,7 @@
possible to use more than four parameters. */
#undef INTERNAL_SYSCALL
#ifdef I386_USE_SYSENTER
-# ifdef SHARED
+# if defined SHARED || defined __PIC__
# define INTERNAL_SYSCALL(name, err, nr, args...) \
({ \
register unsigned int resultvar; \
@@ -384,6 +384,18 @@
: "0" (name), "i" (offsetof (tcbhead_t, sysinfo)) \
ASMFMT_##nr(args) : "memory", "cc"); \
(int) resultvar; })
+# define INTERNAL_SYSCALL_NOSYSENTER(name, err, nr, args...) \
+ ({ \
+ register unsigned int resultvar; \
+ EXTRAVAR_##nr \
+ asm volatile ( \
+ LOADARGS_NOSYSENTER_##nr \
+ "movl %1, %%eax\n\t" \
+ "int $0x80\n\t" \
+ RESTOREARGS_NOSYSENTER_##nr \
+ : "=a" (resultvar) \
+ : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc"); \
+ (int) resultvar; })
# else
# define INTERNAL_SYSCALL(name, err, nr, args...) \
({ \
@@ -447,12 +459,20 @@
#define LOADARGS_0
#ifdef __PIC__
-# if defined I386_USE_SYSENTER && defined SHARED
+# if defined I386_USE_SYSENTER && ( defined SHARED || defined __PIC__ )
# define LOADARGS_1 \
"bpushl .L__X'%k3, %k3\n\t"
# define LOADARGS_5 \
"movl %%ebx, %4\n\t" \
"movl %3, %%ebx\n\t"
+# define LOADARGS_NOSYSENTER_1 \
+ "bpushl .L__X'%k2, %k2\n\t"
+# define LOADARGS_NOSYSENTER_2 LOADARGS_NOSYSENTER_1
+# define LOADARGS_NOSYSENTER_3 LOADARGS_3
+# define LOADARGS_NOSYSENTER_4 LOADARGS_3
+# define LOADARGS_NOSYSENTER_5 \
+ "movl %%ebx, %3\n\t" \
+ "movl %2, %%ebx\n\t"
# else
# define LOADARGS_1 \
"bpushl .L__X'%k2, %k2\n\t"
@@ -474,11 +495,18 @@
#define RESTOREARGS_0
#ifdef __PIC__
-# if defined I386_USE_SYSENTER && defined SHARED
+# if defined I386_USE_SYSENTER && ( defined SHARED || defined __PIC__ )
# define RESTOREARGS_1 \
"bpopl .L__X'%k3, %k3\n\t"
# define RESTOREARGS_5 \
"movl %4, %%ebx"
+# define RESTOREARGS_NOSYSENTER_1 \
+ "bpopl .L__X'%k2, %k2\n\t"
+# define RESTOREARGS_NOSYSENTER_2 RESTOREARGS_NOSYSENTER_1
+# define RESTOREARGS_NOSYSENTER_3 RESTOREARGS_3
+# define RESTOREARGS_NOSYSENTER_4 RESTOREARGS_3
+# define RESTOREARGS_NOSYSENTER_5 \
+ "movl %3, %%ebx"
# else
# define RESTOREARGS_1 \
"bpopl .L__X'%k2, %k2\n\t"

View File

@ -0,0 +1,39 @@
Change link commands for glibc executables to build PIEs
Patch by Kevin F. Quinn <kevquinn@gentoo.org>
--- Makeconfig
+++ Makeconfig
@@ -415,10 +415,10 @@
# Command for linking programs with the C library.
ifndef +link
-+link = $(CC) -nostdlib -nostartfiles -o $@ \
++link = $(CC) -nostdlib -nostartfiles -fPIE -pie -o $@ \
$(sysdep-LDFLAGS) $(config-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \
$(combreloc-LDFLAGS) $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \
- $(addprefix $(csu-objpfx),$(start-installed-name)) \
+ $(addprefix $(csu-objpfx),S$(start-installed-name)) \
$(+preinit) $(+prector) \
$(filter-out $(addprefix $(csu-objpfx),start.o \
$(start-installed-name))\
@@ -429,7 +429,7 @@
ifndef +link-static
+link-static = $(CC) -nostdlib -nostartfiles -static -o $@ \
$(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \
- $(addprefix $(csu-objpfx),$(static-start-installed-name)) \
+ $(addprefix $(csu-objpfx),S$(static-start-installed-name)) \
$(+preinit) $(+prector) \
$(filter-out $(addprefix $(csu-objpfx),start.o \
$(start-installed-name))\
@@ -528,8 +528,8 @@
ifeq ($(elf),yes)
+preinit = $(addprefix $(csu-objpfx),crti.o)
+postinit = $(addprefix $(csu-objpfx),crtn.o)
-+prector = `$(CC) --print-file-name=crtbegin.o`
-+postctor = `$(CC) --print-file-name=crtend.o`
++prector = `$(CC) --print-file-name=crtbeginS.o`
++postctor = `$(CC) --print-file-name=crtendS.o`
+interp = $(addprefix $(elf-objpfx),interp.os)
endif
csu-objpfx = $(common-objpfx)csu/

View File

@ -0,0 +1,321 @@
/* Copyright (C) 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
/* Copyright (C) 2006-2007 Gentoo Foundation Inc.
* License terms as above.
*
* Hardened Gentoo SSP handler
*
* An SSP failure handler that does not use functions from the rest of
* glibc; it uses the INTERNAL_SYSCALL methods directly. This ensures
* no possibility of recursion into the handler.
*
* Direct all bug reports to http://bugs.gentoo.org/
*
* Re-written from the glibc-2.3 Hardened Gentoo SSP handler
* by Kevin F. Quinn - <kevquinn[@]gentoo.org>
*
* The following people contributed to the glibc-2.3 Hardened
* Gentoo SSP handler, from which this implementation draws much:
*
* 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>
* Mike Frysinger <vapier[@]gentoo.org>
*/
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sysdep-cancel.h>
#include <sys/syscall.h>
#include <bp-checks.h>
#include <kernel-features.h>
#include <alloca.h>
/* from sysdeps */
#include <socketcall.h>
/* for the stuff in bits/socket.h */
#include <sys/socket.h>
#include <sys/un.h>
/* Sanity check on SYSCALL macro names - force compilation
* failure if the names used here do not exist
*/
#if !defined __NR_socketcall && !defined __NR_socket
# error Cannot do syscall socket or socketcall
#endif
#if !defined __NR_socketcall && !defined __NR_connect
# error Cannot do syscall connect or socketcall
#endif
#ifndef __NR_write
# error Cannot do syscall write
#endif
#ifndef __NR_close
# error Cannot do syscall close
#endif
#ifndef __NR_getpid
# error Cannot do syscall getpid
#endif
#ifndef __NR_kill
# error Cannot do syscall kill
#endif
#ifndef __NR_exit
# error Cannot do syscall exit
#endif
#ifdef SSP_SMASH_DUMPS_CORE
# define ENABLE_SSP_SMASH_DUMPS_CORE 1
# if !defined _KERNEL_NSIG && !defined _NSIG
# error No _NSIG or _KERNEL_NSIG for rt_sigaction
# endif
# if !defined __NR_sigaction && !defined __NR_rt_sigaction
# error Cannot do syscall sigaction or rt_sigaction
# endif
/* Although rt_sigaction expects sizeof(sigset_t) - it expects the size
* of the _kernel_ sigset_t which is not the same as the user sigset_t.
* Most arches have this as _NSIG bits - mips has _KERNEL_NSIG bits for
* some reason.
*/
# ifdef _KERNEL_NSIG
# define _SSP_NSIG _KERNEL_NSIG
# else
# define _SSP_NSIG _NSIG
# endif
#else
# define _SSP_NSIG 0
# define ENABLE_SSP_SMASH_DUMPS_CORE 0
#endif
/* Define DO_SIGACTION - default to newer rt signal interface but
* fallback to old as needed.
*/
#ifdef __NR_rt_sigaction
# define DO_SIGACTION(signum, act, oldact) \
INLINE_SYSCALL(rt_sigaction, 4, signum, act, oldact, _SSP_NSIG/8)
#else
# define DO_SIGACTION(signum, act, oldact) \
INLINE_SYSCALL(sigaction, 3, signum, act, oldact)
#endif
/* Define DO_SOCKET/DO_CONNECT functions to deal with socketcall vs socket/connect */
#if defined(__NR_socket) && defined(__NR_connect)
# define USE_OLD_SOCKETCALL 0
#else
# define USE_OLD_SOCKETCALL 1
#endif
/* stub out the __NR_'s so we can let gcc optimize away dead code */
#ifndef __NR_socketcall
# define __NR_socketcall 0
#endif
#ifndef __NR_socket
# define __NR_socket 0
#endif
#ifndef __NR_connect
# define __NR_connect 0
#endif
#define DO_SOCKET(result, domain, type, protocol) \
do { \
if (USE_OLD_SOCKETCALL) { \
socketargs[0] = domain; \
socketargs[1] = type; \
socketargs[2] = protocol; \
socketargs[3] = 0; \
result = INLINE_SYSCALL(socketcall, 2, SOCKOP_socket, socketargs); \
} else \
result = INLINE_SYSCALL(socket, 3, domain, type, protocol); \
} while (0)
#define DO_CONNECT(result, sockfd, serv_addr, addrlen) \
do { \
if (USE_OLD_SOCKETCALL) { \
socketargs[0] = sockfd; \
socketargs[1] = (unsigned long int)serv_addr; \
socketargs[2] = addrlen; \
socketargs[3] = 0; \
result = INLINE_SYSCALL(socketcall, 2, SOCKOP_connect, socketargs); \
} else \
result = INLINE_SYSCALL(connect, 3, sockfd, serv_addr, addrlen); \
} while (0)
#ifndef _PATH_LOG
# define _PATH_LOG "/dev/log"
#endif
static const char path_log[] = _PATH_LOG;
/* For building glibc with SSP switched on, define __progname to a
* constant if building for the run-time loader, to avoid pulling
* in more of libc.so into ld.so
*/
#ifdef IS_IN_rtld
static char *__progname = "<rtld>";
#else
extern char *__progname;
#endif
/* Common handler code, used by stack_chk_fail and __stack_smash_handler
* Inlined to ensure no self-references to the handler within itself.
* Data static to avoid putting more than necessary on the stack,
* to aid core debugging.
*/
__attribute__ ((__noreturn__ , __always_inline__))
static inline void
__hardened_gentoo_stack_chk_fail(char func[], int damaged)
{
#define MESSAGE_BUFSIZ 256
static pid_t pid;
static int plen, i;
static char message[MESSAGE_BUFSIZ];
static const char msg_ssa[] = ": stack smashing attack";
static const char msg_inf[] = " in function ";
static const char msg_ssd[] = "*** stack smashing detected ***: ";
static const char msg_terminated[] = " - terminated\n";
static const char msg_report[] = "Report to http://bugs.gentoo.org/\n";
static const char msg_unknown[] = "<unknown>";
static int log_socket, connect_result;
static struct sockaddr_un sock;
static unsigned long int socketargs[4];
/* Build socket address
*/
sock.sun_family = AF_UNIX;
i = 0;
while ((path_log[i] != '\0') && (i<(sizeof(sock.sun_path)-1))) {
sock.sun_path[i] = path_log[i];
i++;
}
sock.sun_path[i] = '\0';
/* Try SOCK_DGRAM connection to syslog */
connect_result = -1;
DO_SOCKET(log_socket, AF_UNIX, SOCK_DGRAM, 0);
if (log_socket != -1)
DO_CONNECT(connect_result, log_socket, &sock, sizeof(sock));
if (connect_result == -1) {
if (log_socket != -1)
INLINE_SYSCALL(close, 1, log_socket);
/* Try SOCK_STREAM connection to syslog */
DO_SOCKET(log_socket, AF_UNIX, SOCK_STREAM, 0);
if (log_socket != -1)
DO_CONNECT(connect_result, log_socket, &sock, sizeof(sock));
}
/* Build message. Messages are generated both in the old style and new style,
* so that log watchers that are configured for the old-style message continue
* to work.
*/
#define strconcat(str) \
{i=0; while ((str[i] != '\0') && ((i+plen)<(MESSAGE_BUFSIZ-1))) \
{\
message[plen+i]=str[i];\
i++;\
}\
plen+=i;}
/* R.Henderson post-gcc-4 style message */
plen = 0;
strconcat(msg_ssd);
if (__progname != (char *)0)
strconcat(__progname)
else
strconcat(msg_unknown);
strconcat(msg_terminated);
/* Write out error message to STDERR, to syslog if open */
INLINE_SYSCALL(write, 3, STDERR_FILENO, message, plen);
if (connect_result != -1)
INLINE_SYSCALL(write, 3, log_socket, message, plen);
/* Dr. Etoh pre-gcc-4 style message */
plen = 0;
if (__progname != (char *)0)
strconcat(__progname)
else
strconcat(msg_unknown);
strconcat(msg_ssa);
strconcat(msg_inf);
if (func != NULL)
strconcat(func)
else
strconcat(msg_unknown);
strconcat(msg_terminated);
/* Write out error message to STDERR, to syslog if open */
INLINE_SYSCALL(write, 3, STDERR_FILENO, message, plen);
if (connect_result != -1)
INLINE_SYSCALL(write, 3, log_socket, message, plen);
/* Direct reports to bugs.gentoo.org */
plen=0;
strconcat(msg_report);
message[plen++]='\0';
/* Write out error message to STDERR, to syslog if open */
INLINE_SYSCALL(write, 3, STDERR_FILENO, message, plen);
if (connect_result != -1)
INLINE_SYSCALL(write, 3, log_socket, message, plen);
if (log_socket != -1)
INLINE_SYSCALL(close, 1, log_socket);
/* Suicide */
pid = INLINE_SYSCALL(getpid, 0);
if (ENABLE_SSP_SMASH_DUMPS_CORE) {
static struct sigaction default_abort_act;
/* Remove any user-supplied handler for SIGABRT, before using it */
default_abort_act.sa_handler = SIG_DFL;
default_abort_act.sa_sigaction = NULL;
__sigfillset(&default_abort_act.sa_mask);
default_abort_act.sa_flags = 0;
if (DO_SIGACTION(SIGABRT, &default_abort_act, NULL) == 0)
INLINE_SYSCALL(kill, 2, pid, SIGABRT);
}
/* Note; actions cannot be added to SIGKILL */
INLINE_SYSCALL(kill, 2, pid, SIGKILL);
/* In case the kill didn't work, exit anyway
* The loop prevents gcc thinking this routine returns
*/
while (1)
INLINE_SYSCALL(exit, 0);
}
__attribute__ ((__noreturn__))
void __stack_chk_fail(void)
{
__hardened_gentoo_stack_chk_fail(NULL, 0);
}
#ifdef ENABLE_OLD_SSP_COMPAT
__attribute__ ((__noreturn__))
void __stack_smash_handler(char func[], int damaged)
{
__hardened_gentoo_stack_chk_fail(func, damaged);
}
#endif

View File

@ -0,0 +1,273 @@
When building glibc PIE (which is not something upstream support),
several modifications are necessary to the glibc build process.
First, any syscalls in PIEs must be of the PIC variant, otherwise
textrels ensue. Then, any syscalls made before the initialisation
of the TLS will fail on i386, as the sysenter variant on i386 uses
the TLS, giving rise to a chicken-and-egg situation. This patch
defines a PIC syscall variant that doesn't use sysenter, even when the sysenter
version is normally used, and uses the non-sysenter version for the brk
syscall that is performed by the TLS initialisation. Further, the TLS
initialisation is moved in this case prior to the initialisation of
dl_osversion, as that requires further syscalls.
csu/libc-start.c: Move initial TLS initialization to before the
initialisation of dl_osversion, when INTERNAL_SYSCALL_NOSYSENTER is defined
csu/libc-tls.c: Use the no-sysenter version of sbrk when
INTERNAL_SYSCALL_NOSYSENTER is defined.
misc/sbrk.c: Define a no-sysenter version of sbrk, using the no-sysenter
version of brk - if INTERNAL_SYSCALL_NOSYSENTER is defined.
misc/brk.c: Define a no-sysenter version of brk if
INTERNAL_SYSCALL_NOSYSENTER is defined.
sysdeps/unix/sysv/linux/i386/sysdep.h: Define INTERNAL_SYSCALL_NOSYSENTER
Make INTERNAL_SYSCALL always use the PIC variant, even if not SHARED.
Patch by Kevin F. Quinn <kevquinn@gentoo.org>
--- csu/libc-start.c
+++ csu/libc-start.c
@@ -28,6 +28,7 @@
extern int __libc_multiple_libcs;
#include <tls.h>
+#include <sysdep.h>
#ifndef SHARED
# include <dl-osinfo.h>
extern void __pthread_initialize_minimal (void);
@@ -129,6 +130,11 @@
# endif
_dl_aux_init (auxvec);
# endif
+# ifdef INTERNAL_SYSCALL_NOSYSENTER
+ /* Do the initial TLS initialization before _dl_osversion,
+ since the latter uses the uname syscall. */
+ __pthread_initialize_minimal ();
+# endif
# ifdef DL_SYSDEP_OSCHECK
if (!__libc_multiple_libcs)
{
@@ -138,10 +144,12 @@
}
# endif
+# ifndef INTERNAL_SYSCALL_NOSYSENTER
/* Initialize the thread library at least a bit since the libgcc
functions are using thread functions if these are available and
we need to setup errno. */
__pthread_initialize_minimal ();
+# endif
#endif
# ifndef SHARED
--- csu/libc-tls.c
+++ csu/libc-tls.c
@@ -23,6 +23,7 @@
#include <unistd.h>
#include <stdio.h>
#include <sys/param.h>
+#include <sysdep.h>
#ifdef SHARED
@@ -29,6 +30,9 @@
#error makefile bug, this file is for static only
#endif
+#ifdef INTERNAL_SYSCALL_NOSYSENTER
+extern void *__sbrk_nosysenter (intptr_t __delta);
+#endif
extern ElfW(Phdr) *_dl_phdr;
extern size_t _dl_phnum;
@@ -141,14 +145,26 @@
The initialized value of _dl_tls_static_size is provided by dl-open.c
to request some surplus that permits dynamic loading of modules with
- IE-model TLS. */
+ IE-model TLS.
+
+ Where the normal sbrk would use a syscall that needs the TLS (i386)
+ use the special non-sysenter version instead. */
#if TLS_TCB_AT_TP
tcb_offset = roundup (memsz + GL(dl_tls_static_size), tcbalign);
+# ifdef INTERNAL_SYSCALL_NOSYSENTER
+ tlsblock = __sbrk_nosysenter (tcb_offset + tcbsize + max_align);
+# else
tlsblock = __sbrk (tcb_offset + tcbsize + max_align);
+# endif
#elif TLS_DTV_AT_TP
tcb_offset = roundup (tcbsize, align ?: 1);
+# ifdef INTERNAL_SYSCALL_NOSYSENTER
+ tlsblock = __sbrk_nosysenter (tcb_offset + memsz + max_align
+ + TLS_PRE_TCB_SIZE + GL(dl_tls_static_size));
+# else
tlsblock = __sbrk (tcb_offset + memsz + max_align
+ TLS_PRE_TCB_SIZE + GL(dl_tls_static_size));
+# endif
tlsblock += TLS_PRE_TCB_SIZE;
#else
/* In case a model with a different layout for the TCB and DTV
--- misc/sbrk.c
+++ misc/sbrk.c
@@ -18,6 +18,7 @@
#include <unistd.h>
#include <errno.h>
+#include <sysdep.h>
/* Defined in brk.c. */
extern void *__curbrk;
@@ -29,6 +30,35 @@
/* Extend the process's data space by INCREMENT.
If INCREMENT is negative, shrink data space by - INCREMENT.
Return start of new space allocated, or -1 for errors. */
+#ifdef INTERNAL_SYSCALL_NOSYSENTER
+/* This version is used by csu/libc-tls.c whem initialising the TLS
+ if the SYSENTER version requires the TLS (which it does on i386).
+ Obviously using the TLS before it is initialised is broken. */
+extern int __brk_nosysenter (void *addr);
+void *
+__sbrk_nosysenter (intptr_t increment)
+{
+ void *oldbrk;
+
+ /* If this is not part of the dynamic library or the library is used
+ via dynamic loading in a statically linked program update
+ __curbrk from the kernel's brk value. That way two separate
+ instances of __brk and __sbrk can share the heap, returning
+ interleaved pieces of it. */
+ if (__curbrk == NULL || __libc_multiple_libcs)
+ if (__brk_nosysenter (0) < 0) /* Initialize the break. */
+ return (void *) -1;
+
+ if (increment == 0)
+ return __curbrk;
+
+ oldbrk = __curbrk;
+ if (__brk_nosysenter (oldbrk + increment) < 0)
+ return (void *) -1;
+
+ return oldbrk;
+}
+#endif
void *
__sbrk (intptr_t increment)
{
--- sysdeps/unix/sysv/linux/i386/brk.c
+++ sysdeps/unix/sysv/linux/i386/brk.c
@@ -31,6 +31,30 @@
linker. */
weak_alias (__curbrk, ___brk_addr)
+#ifdef INTERNAL_SYSCALL_NOSYSENTER
+/* This version is used by csu/libc-tls.c whem initialising the TLS
+ * if the SYSENTER version requires the TLS (which it does on i386).
+ * Obviously using the TLS before it is initialised is broken. */
+int
+__brk_nosysenter (void *addr)
+{
+ void *__unbounded newbrk;
+
+ INTERNAL_SYSCALL_DECL (err);
+ newbrk = (void *__unbounded) INTERNAL_SYSCALL_NOSYSENTER (brk, err, 1,
+ __ptrvalue (addr));
+
+ __curbrk = newbrk;
+
+ if (newbrk < addr)
+ {
+ __set_errno (ENOMEM);
+ return -1;
+ }
+
+ return 0;
+}
+#endif
int
__brk (void *addr)
{
--- sysdeps/unix/sysv/linux/i386/sysdep.h
+++ sysdeps/unix/sysv/linux/i386/sysdep.h
@@ -187,7 +187,7 @@
/* The original calling convention for system calls on Linux/i386 is
to use int $0x80. */
#ifdef I386_USE_SYSENTER
-# ifdef SHARED
+# if defined SHARED || defined __PIC__
# define ENTER_KERNEL call *%gs:SYSINFO_OFFSET
# else
# define ENTER_KERNEL call *_dl_sysinfo
@@ -358,7 +358,7 @@
possible to use more than four parameters. */
#undef INTERNAL_SYSCALL
#ifdef I386_USE_SYSENTER
-# ifdef SHARED
+# if defined SHARED || defined __PIC__
# define INTERNAL_SYSCALL(name, err, nr, args...) \
({ \
register unsigned int resultvar; \
@@ -384,6 +384,18 @@
: "0" (name), "i" (offsetof (tcbhead_t, sysinfo)) \
ASMFMT_##nr(args) : "memory", "cc"); \
(int) resultvar; })
+# define INTERNAL_SYSCALL_NOSYSENTER(name, err, nr, args...) \
+ ({ \
+ register unsigned int resultvar; \
+ EXTRAVAR_##nr \
+ asm volatile ( \
+ LOADARGS_NOSYSENTER_##nr \
+ "movl %1, %%eax\n\t" \
+ "int $0x80\n\t" \
+ RESTOREARGS_NOSYSENTER_##nr \
+ : "=a" (resultvar) \
+ : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc"); \
+ (int) resultvar; })
# else
# define INTERNAL_SYSCALL(name, err, nr, args...) \
({ \
@@ -447,12 +459,20 @@
#define LOADARGS_0
#ifdef __PIC__
-# if defined I386_USE_SYSENTER && defined SHARED
+# if defined I386_USE_SYSENTER && ( defined SHARED || defined __PIC__ )
# define LOADARGS_1 \
"bpushl .L__X'%k3, %k3\n\t"
# define LOADARGS_5 \
"movl %%ebx, %4\n\t" \
"movl %3, %%ebx\n\t"
+# define LOADARGS_NOSYSENTER_1 \
+ "bpushl .L__X'%k2, %k2\n\t"
+# define LOADARGS_NOSYSENTER_2 LOADARGS_NOSYSENTER_1
+# define LOADARGS_NOSYSENTER_3 LOADARGS_3
+# define LOADARGS_NOSYSENTER_4 LOADARGS_3
+# define LOADARGS_NOSYSENTER_5 \
+ "movl %%ebx, %3\n\t" \
+ "movl %2, %%ebx\n\t"
# else
# define LOADARGS_1 \
"bpushl .L__X'%k2, %k2\n\t"
@@ -474,11 +495,18 @@
#define RESTOREARGS_0
#ifdef __PIC__
-# if defined I386_USE_SYSENTER && defined SHARED
+# if defined I386_USE_SYSENTER && ( defined SHARED || defined __PIC__ )
# define RESTOREARGS_1 \
"bpopl .L__X'%k3, %k3\n\t"
# define RESTOREARGS_5 \
"movl %4, %%ebx"
+# define RESTOREARGS_NOSYSENTER_1 \
+ "bpopl .L__X'%k2, %k2\n\t"
+# define RESTOREARGS_NOSYSENTER_2 RESTOREARGS_NOSYSENTER_1
+# define RESTOREARGS_NOSYSENTER_3 RESTOREARGS_3
+# define RESTOREARGS_NOSYSENTER_4 RESTOREARGS_3
+# define RESTOREARGS_NOSYSENTER_5 \
+ "movl %3, %%ebx"
# else
# define RESTOREARGS_1 \
"bpopl .L__X'%k2, %k2\n\t"

View File

@ -0,0 +1,273 @@
When building glibc PIE (which is not something upstream support),
several modifications are necessary to the glibc build process.
First, any syscalls in PIEs must be of the PIC variant, otherwise
textrels ensue. Then, any syscalls made before the initialisation
of the TLS will fail on i386, as the sysenter variant on i386 uses
the TLS, giving rise to a chicken-and-egg situation. This patch
defines a PIC syscall variant that doesn't use sysenter, even when the sysenter
version is normally used, and uses the non-sysenter version for the brk
syscall that is performed by the TLS initialisation. Further, the TLS
initialisation is moved in this case prior to the initialisation of
dl_osversion, as that requires further syscalls.
csu/libc-start.c: Move initial TLS initialization to before the
initialisation of dl_osversion, when INTERNAL_SYSCALL_NOSYSENTER is defined
csu/libc-tls.c: Use the no-sysenter version of sbrk when
INTERNAL_SYSCALL_NOSYSENTER is defined.
misc/sbrk.c: Define a no-sysenter version of sbrk, using the no-sysenter
version of brk - if INTERNAL_SYSCALL_NOSYSENTER is defined.
misc/brk.c: Define a no-sysenter version of brk if
INTERNAL_SYSCALL_NOSYSENTER is defined.
sysdeps/unix/sysv/linux/i386/sysdep.h: Define INTERNAL_SYSCALL_NOSYSENTER
Make INTERNAL_SYSCALL always use the PIC variant, even if not SHARED.
Patch by Kevin F. Quinn <kevquinn@gentoo.org>
--- csu/libc-start.c
+++ csu/libc-start.c
@@ -28,6 +28,7 @@
extern int __libc_multiple_libcs;
#include <tls.h>
+#include <sysdep.h>
#ifndef SHARED
# include <dl-osinfo.h>
extern void __pthread_initialize_minimal (void);
@@ -129,6 +130,11 @@
# endif
_dl_aux_init (auxvec);
# endif
+# ifdef INTERNAL_SYSCALL_NOSYSENTER
+ /* Do the initial TLS initialization before _dl_osversion,
+ since the latter uses the uname syscall. */
+ __pthread_initialize_minimal ();
+# endif
# ifdef DL_SYSDEP_OSCHECK
if (!__libc_multiple_libcs)
{
@@ -138,10 +144,12 @@
}
# endif
+# ifndef INTERNAL_SYSCALL_NOSYSENTER
/* Initialize the thread library at least a bit since the libgcc
functions are using thread functions if these are available and
we need to setup errno. */
__pthread_initialize_minimal ();
+# endif
/* Set up the stack checker's canary. */
uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard ();
--- csu/libc-tls.c
+++ csu/libc-tls.c
@@ -23,6 +23,7 @@
#include <unistd.h>
#include <stdio.h>
#include <sys/param.h>
+#include <sysdep.h>
#ifdef SHARED
@@ -29,6 +30,9 @@
#error makefile bug, this file is for static only
#endif
+#ifdef INTERNAL_SYSCALL_NOSYSENTER
+extern void *__sbrk_nosysenter (intptr_t __delta);
+#endif
extern ElfW(Phdr) *_dl_phdr;
extern size_t _dl_phnum;
@@ -141,14 +145,26 @@
The initialized value of _dl_tls_static_size is provided by dl-open.c
to request some surplus that permits dynamic loading of modules with
- IE-model TLS. */
+ IE-model TLS.
+
+ Where the normal sbrk would use a syscall that needs the TLS (i386)
+ use the special non-sysenter version instead. */
#if TLS_TCB_AT_TP
tcb_offset = roundup (memsz + GL(dl_tls_static_size), tcbalign);
+# ifdef INTERNAL_SYSCALL_NOSYSENTER
+ tlsblock = __sbrk_nosysenter (tcb_offset + tcbsize + max_align);
+# else
tlsblock = __sbrk (tcb_offset + tcbsize + max_align);
+# endif
#elif TLS_DTV_AT_TP
tcb_offset = roundup (tcbsize, align ?: 1);
+# ifdef INTERNAL_SYSCALL_NOSYSENTER
+ tlsblock = __sbrk_nosysenter (tcb_offset + memsz + max_align
+ + TLS_PRE_TCB_SIZE + GL(dl_tls_static_size));
+# else
tlsblock = __sbrk (tcb_offset + memsz + max_align
+ TLS_PRE_TCB_SIZE + GL(dl_tls_static_size));
+# endif
tlsblock += TLS_PRE_TCB_SIZE;
#else
/* In case a model with a different layout for the TCB and DTV
--- misc/sbrk.c
+++ misc/sbrk.c
@@ -18,6 +18,7 @@
#include <unistd.h>
#include <errno.h>
+#include <sysdep.h>
/* Defined in brk.c. */
extern void *__curbrk;
@@ -29,6 +30,35 @@
/* Extend the process's data space by INCREMENT.
If INCREMENT is negative, shrink data space by - INCREMENT.
Return start of new space allocated, or -1 for errors. */
+#ifdef INTERNAL_SYSCALL_NOSYSENTER
+/* This version is used by csu/libc-tls.c whem initialising the TLS
+ if the SYSENTER version requires the TLS (which it does on i386).
+ Obviously using the TLS before it is initialised is broken. */
+extern int __brk_nosysenter (void *addr);
+void *
+__sbrk_nosysenter (intptr_t increment)
+{
+ void *oldbrk;
+
+ /* If this is not part of the dynamic library or the library is used
+ via dynamic loading in a statically linked program update
+ __curbrk from the kernel's brk value. That way two separate
+ instances of __brk and __sbrk can share the heap, returning
+ interleaved pieces of it. */
+ if (__curbrk == NULL || __libc_multiple_libcs)
+ if (__brk_nosysenter (0) < 0) /* Initialize the break. */
+ return (void *) -1;
+
+ if (increment == 0)
+ return __curbrk;
+
+ oldbrk = __curbrk;
+ if (__brk_nosysenter (oldbrk + increment) < 0)
+ return (void *) -1;
+
+ return oldbrk;
+}
+#endif
void *
__sbrk (intptr_t increment)
{
--- sysdeps/unix/sysv/linux/i386/brk.c
+++ sysdeps/unix/sysv/linux/i386/brk.c
@@ -31,6 +31,30 @@
linker. */
weak_alias (__curbrk, ___brk_addr)
+#ifdef INTERNAL_SYSCALL_NOSYSENTER
+/* This version is used by csu/libc-tls.c whem initialising the TLS
+ * if the SYSENTER version requires the TLS (which it does on i386).
+ * Obviously using the TLS before it is initialised is broken. */
+int
+__brk_nosysenter (void *addr)
+{
+ void *__unbounded newbrk;
+
+ INTERNAL_SYSCALL_DECL (err);
+ newbrk = (void *__unbounded) INTERNAL_SYSCALL_NOSYSENTER (brk, err, 1,
+ __ptrvalue (addr));
+
+ __curbrk = newbrk;
+
+ if (newbrk < addr)
+ {
+ __set_errno (ENOMEM);
+ return -1;
+ }
+
+ return 0;
+}
+#endif
int
__brk (void *addr)
{
--- sysdeps/unix/sysv/linux/i386/sysdep.h
+++ sysdeps/unix/sysv/linux/i386/sysdep.h
@@ -187,7 +187,7 @@
/* The original calling convention for system calls on Linux/i386 is
to use int $0x80. */
#ifdef I386_USE_SYSENTER
-# ifdef SHARED
+# if defined SHARED || defined __PIC__
# define ENTER_KERNEL call *%gs:SYSINFO_OFFSET
# else
# define ENTER_KERNEL call *_dl_sysinfo
@@ -358,7 +358,7 @@
possible to use more than four parameters. */
#undef INTERNAL_SYSCALL
#ifdef I386_USE_SYSENTER
-# ifdef SHARED
+# if defined SHARED || defined __PIC__
# define INTERNAL_SYSCALL(name, err, nr, args...) \
({ \
register unsigned int resultvar; \
@@ -384,6 +384,18 @@
: "0" (name), "i" (offsetof (tcbhead_t, sysinfo)) \
ASMFMT_##nr(args) : "memory", "cc"); \
(int) resultvar; })
+# define INTERNAL_SYSCALL_NOSYSENTER(name, err, nr, args...) \
+ ({ \
+ register unsigned int resultvar; \
+ EXTRAVAR_##nr \
+ asm volatile ( \
+ LOADARGS_NOSYSENTER_##nr \
+ "movl %1, %%eax\n\t" \
+ "int $0x80\n\t" \
+ RESTOREARGS_NOSYSENTER_##nr \
+ : "=a" (resultvar) \
+ : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc"); \
+ (int) resultvar; })
# else
# define INTERNAL_SYSCALL(name, err, nr, args...) \
({ \
@@ -447,12 +459,20 @@
#define LOADARGS_0
#ifdef __PIC__
-# if defined I386_USE_SYSENTER && defined SHARED
+# if defined I386_USE_SYSENTER && ( defined SHARED || defined __PIC__ )
# define LOADARGS_1 \
"bpushl .L__X'%k3, %k3\n\t"
# define LOADARGS_5 \
"movl %%ebx, %4\n\t" \
"movl %3, %%ebx\n\t"
+# define LOADARGS_NOSYSENTER_1 \
+ "bpushl .L__X'%k2, %k2\n\t"
+# define LOADARGS_NOSYSENTER_2 LOADARGS_NOSYSENTER_1
+# define LOADARGS_NOSYSENTER_3 LOADARGS_3
+# define LOADARGS_NOSYSENTER_4 LOADARGS_3
+# define LOADARGS_NOSYSENTER_5 \
+ "movl %%ebx, %3\n\t" \
+ "movl %2, %%ebx\n\t"
# else
# define LOADARGS_1 \
"bpushl .L__X'%k2, %k2\n\t"
@@ -474,11 +495,18 @@
#define RESTOREARGS_0
#ifdef __PIC__
-# if defined I386_USE_SYSENTER && defined SHARED
+# if defined I386_USE_SYSENTER && ( defined SHARED || defined __PIC__ )
# define RESTOREARGS_1 \
"bpopl .L__X'%k3, %k3\n\t"
# define RESTOREARGS_5 \
"movl %4, %%ebx"
+# define RESTOREARGS_NOSYSENTER_1 \
+ "bpopl .L__X'%k2, %k2\n\t"
+# define RESTOREARGS_NOSYSENTER_2 RESTOREARGS_NOSYSENTER_1
+# define RESTOREARGS_NOSYSENTER_3 RESTOREARGS_3
+# define RESTOREARGS_NOSYSENTER_4 RESTOREARGS_3
+# define RESTOREARGS_NOSYSENTER_5 \
+ "movl %3, %%ebx"
# else
# define RESTOREARGS_1 \
"bpopl .L__X'%k2, %k2\n\t"

View File

@ -0,0 +1,310 @@
# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/sys-libs/glibc/files/eblits/common.eblit,v 1.34 2014/01/16 17:38:31 vapier Exp $
alt_prefix() {
is_crosscompile && echo /usr/${CTARGET}
}
: ${ED:=${D}}
: ${EROOT:=${ROOT}}
# We need to be able to set alternative headers for
# compiling for non-native platform
# Will also become useful for testing kernel-headers without screwing up
# the whole system.
# note: intentionally undocumented.
alt_headers() {
echo ${ALT_HEADERS:=$(alt_prefix)/usr/include}
}
alt_build_headers() {
if [[ -z ${ALT_BUILD_HEADERS} ]] ; then
ALT_BUILD_HEADERS=$(alt_headers)
if tc-is-cross-compiler ; then
ALT_BUILD_HEADERS=${ROOT}$(alt_headers)
if [[ ! -e ${ALT_BUILD_HEADERS}/linux/version.h ]] ; then
local header_path=$(echo '#include <linux/version.h>' | $(tc-getCPP ${CTARGET}) ${CFLAGS} 2>&1 | grep -o '[^"]*linux/version.h')
ALT_BUILD_HEADERS=${header_path%/linux/version.h}
fi
fi
fi
echo "${ALT_BUILD_HEADERS}"
}
alt_libdir() {
echo $(alt_prefix)/$(get_libdir)
}
alt_usrlibdir() {
echo $(alt_prefix)/usr/$(get_libdir)
}
setup_target_flags() {
# This largely mucks with compiler flags. None of which should matter
# when building up just the headers.
just_headers && return 0
case $(tc-arch) in
x86)
# -march needed for #185404 #199334
if ! glibc_compile_test "" 'void f(int i, void *p) {if (__sync_fetch_and_add(&i, 1)) f(i, p);}\nint main(){return 0;}\n' 2>/dev/null ; then
local t=${CTARGET_OPT:-${CTARGET}}
t=${t%%-*}
filter-flags '-march=*'
export CFLAGS="-march=${t} ${CFLAGS}"
einfo "Auto adding -march=${t} to CFLAGS #185404"
fi
;;
amd64)
# -march needed for #185404 #199334
if ! glibc_compile_test "${CFLAGS_x86}" 'void f(int i, void *p) {if (__sync_fetch_and_add(&i, 1)) f(i, p);}\nint main(){return 0;}\n' 2>/dev/null ; then
local t=${CTARGET_OPT:-${CTARGET}}
t=${t%%-*}
filter-flags '-march=*'
# ugly, ugly, ugly. ugly.
CFLAGS_x86=$(CFLAGS=${CFLAGS_x86} filter-flags '-march=*'; echo "${CFLAGS}")
export CFLAGS_x86="${CFLAGS_x86} -march=${t}"
einfo "Auto adding -march=${t} to CFLAGS_x86 #185404"
fi
;;
ppc)
append-flags "-freorder-blocks"
;;
sparc)
# Both sparc and sparc64 can use -fcall-used-g6. -g7 is bad, though.
filter-flags "-fcall-used-g7"
append-flags "-fcall-used-g6"
filter-flags "-mvis"
GLIBCMAJOR=$(get_version_component_range 1 ${PV})
GLIBCMINOR=$(get_version_component_range 2 ${PV})
# set CTARGET_OPT so glibc can use cpu-specific .S files for better performance
# - UltraSPARC T1 (niagara) support requires >= glibc 2.8
# - UltraSPARC T2 (niagara2) support requires >= glibc 2.7
if is_crosscompile || [[ ${PROFILE_ARCH} == "sparc64" ]] || { has_multilib_profile && ! tc-is-cross-compiler; } ; then
case ${ABI}:${CTARGET} in
sparc64:*|\
default:sparc64*)
filter-flags -Wa,-xarch -Wa,-A
if is-flagq "-mcpu=niagara2" && [[ ${GLIBCMAJOR}.${GLIBCMINOR} > 2.7 ]] ; then
CTARGET_OPT="sparc64v2-unknown-linux-gnu"
append-flags "-Wa,-xarch=v9b"
export ASFLAGS="${ASFLAGS} -Wa,-xarch=v9b"
elif { is-flagq "-mcpu=niagara" || is-flagq "-mcpu=niagara2" ; } && [[ ${GLIBCMAJOR}.${GLIBCMINOR} > 2.6 ]] ; then
CTARGET_OPT="sparc64v-unknown-linux-gnu"
append-flags "-Wa,-xarch=v9b"
export ASFLAGS="${ASFLAGS} -Wa,-xarch=v9b"
elif is-flagq "-mcpu=ultrasparc3" || is-flagq "-mcpu=niagara" || is-flagq "-mcpu=niagara2"; then
CTARGET_OPT="sparc64b-unknown-linux-gnu"
append-flags "-Wa,-xarch=v9b"
export ASFLAGS="${ASFLAGS} -Wa,-xarch=v9b"
else
CTARGET_OPT="sparc64-unknown-linux-gnu"
append-flags "-Wa,-xarch=v9a"
export ASFLAGS="${ASFLAGS} -Wa,-xarch=v9a"
fi
;;
*)
if is-flagq "-mcpu=niagara2" && [[ ${GLIBCMAJOR}.${GLIBCMINOR} > 2.7 ]] ; then
CTARGET_OPT="sparcv9v2-unknown-linux-gnu"
elif { is-flagq "-mcpu=niagara" || is-flagq "-mcpu=niagara2" ; } && [[ ${GLIBCMAJOR}.${GLIBCMINOR} > 2.6 ]] ; then
CTARGET_OPT="sparcv9v-unknown-linux-gnu"
elif is-flagq "-mcpu=ultrasparc3" || is-flagq "-mcpu=niagara" || is-flagq "-mcpu=niagara2"; then
CTARGET_OPT="sparcv9b-unknown-linux-gnu"
else
CTARGET_OPT="sparcv9-unknown-linux-gnu"
fi
;;
esac
else
if is-flagq "-mcpu=niagara2" && [[ ${GLIBCMAJOR}.${GLIBCMINOR} > 2.7 ]] ; then
CTARGET_OPT="sparcv9v2-unknown-linux-gnu"
elif { is-flagq "-mcpu=niagara" || is-flagq "-mcpu=niagara2" ; } && [[ ${GLIBCMAJOR}.${GLIBCMINOR} > 2.6 ]] ; then
CTARGET_OPT="sparcv9v-unknown-linux-gnu"
elif is-flagq "-mcpu=ultrasparc3" || is-flagq "-mcpu=niagara" || is-flagq "-mcpu=niagara2"; then
CTARGET_OPT="sparcv9b-unknown-linux-gnu"
elif { is_crosscompile && want_nptl; } || is-flagq "-mcpu=ultrasparc2" || is-flagq "-mcpu=ultrasparc"; then
CTARGET_OPT="sparcv9-unknown-linux-gnu"
fi
fi
;;
esac
}
setup_flags() {
# Make sure host make.conf doesn't pollute us
if is_crosscompile || tc-is-cross-compiler ; then
CHOST=${CTARGET} strip-unsupported-flags
fi
# Store our CFLAGS because it's changed depending on which CTARGET
# we are building when pulling glibc on a multilib profile
CFLAGS_BASE=${CFLAGS_BASE-${CFLAGS}}
CFLAGS=${CFLAGS_BASE}
CXXFLAGS_BASE=${CXXFLAGS_BASE-${CXXFLAGS}}
CXXFLAGS=${CXXFLAGS_BASE}
ASFLAGS_BASE=${ASFLAGS_BASE-${ASFLAGS}}
ASFLAGS=${ASFLAGS_BASE}
# Over-zealous CFLAGS can often cause problems. What may work for one
# person may not work for another. To avoid a large influx of bugs
# relating to failed builds, we strip most CFLAGS out to ensure as few
# problems as possible.
strip-flags
strip-unsupported-flags
filter-flags -m32 -m64 -mabi=*
# Bug 492892.
filter-flags -frecord-gcc-switches
unset CBUILD_OPT CTARGET_OPT
if has_multilib_profile ; then
CTARGET_OPT=$(get_abi_CTARGET)
[[ -z ${CTARGET_OPT} ]] && CTARGET_OPT=$(get_abi_CHOST)
fi
setup_target_flags
if [[ -n ${CTARGET_OPT} && ${CBUILD} == ${CHOST} ]] && ! is_crosscompile; then
CBUILD_OPT=${CTARGET_OPT}
fi
# Lock glibc at -O2 -- linuxthreads needs it and we want to be
# conservative here. -fno-strict-aliasing is to work around #155906
filter-flags -O?
append-flags -O2 -fno-strict-aliasing
# Can't build glibc itself with fortify code. Newer versions add
# this flag for us, so no need to do it manually.
version_is_at_least 2.16 ${PV} || append-cppflags -U_FORTIFY_SOURCE
# building glibc with SSP is fraught with difficulty, especially
# due to __stack_chk_fail_local which would mean significant changes
# to the glibc build process. See bug #94325 #293721
gcc-specs-ssp && append-cflags $(test-flags-CC -fno-stack-protector)
if use hardened && gcc-specs-pie ; then
# Force PIC macro definition for all compilations since they're all
# either -fPIC or -fPIE with the default-PIE compiler.
append-cppflags -DPIC
else
# Don't build -fPIE without the default-PIE compiler and the
# hardened-pie patch
filter-flags -fPIE
fi
}
want_nptl() {
[[ -z ${LT_VER} ]] && return 0
want_tls || return 1
use nptl || return 1
# Only list the arches that cannot do NPTL
case $(tc-arch) in
m68k) return 1;;
sparc)
# >= v9 is needed for nptl.
[[ ${PROFILE_ARCH} == "sparc" ]] && return 1
;;
esac
return 0
}
want_linuxthreads() {
[[ -z ${LT_VER} ]] && return 1
use linuxthreads
}
want_tls() {
# Archs that can use TLS (Thread Local Storage)
case $(tc-arch) in
x86)
# requires i486 or better #106556
[[ ${CTARGET} == i[4567]86* ]] && return 0
return 1
;;
esac
return 0
}
want__thread() {
want_tls || return 1
# For some reason --with-tls --with__thread is causing segfaults on sparc32.
[[ ${PROFILE_ARCH} == "sparc" ]] && return 1
[[ -n ${WANT__THREAD} ]] && return ${WANT__THREAD}
# only test gcc -- cant test linking yet
tc-has-tls -c ${CTARGET}
WANT__THREAD=$?
return ${WANT__THREAD}
}
use_multiarch() {
# Make sure binutils is new enough to support indirect functions #336792
# This funky sed supports gold and bfd linkers.
local bver nver
bver=$($(tc-getLD ${CTARGET}) -v | sed -n -r '1{s:[^0-9]*::;s:^([0-9.]*).*:\1:;p}')
case $(tc-arch ${CTARGET}) in
amd64|x86) nver="2.20" ;;
arm) nver="2.22" ;;
hppa) nver="2.23" ;;
ppc|ppc64) nver="2.20" ;;
# ifunc was added in 2.23, but glibc also needs machinemode which is in 2.24.
s390) nver="2.24" ;;
sparc) nver="2.21" ;;
*) return 1 ;;
esac
version_is_at_least ${nver} ${bver}
}
# Setup toolchain variables that had historically
# been defined in the profiles for these archs.
setup_env() {
# silly users
unset LD_RUN_PATH
multilib_env ${CTARGET_OPT:-${CTARGET}}
if is_crosscompile || tc-is-cross-compiler ; then
if ! use multilib ; then
MULTILIB_ABIS=${DEFAULT_ABI}
else
MULTILIB_ABIS=${MULTILIB_ABIS:-${DEFAULT_ABI}}
fi
# If the user has CFLAGS_<CTARGET> in their make.conf, use that,
# and fall back on CFLAGS.
local VAR=CFLAGS_${CTARGET//[-.]/_}
CFLAGS=${!VAR-${CFLAGS}}
fi
setup_flags
export ABI=${ABI:-${DEFAULT_ABI:-default}}
local VAR=CFLAGS_${ABI}
# We need to export CFLAGS with abi information in them because glibc's
# configure script checks CFLAGS for some targets (like mips). Keep
# around the original clean value to avoid appending multiple ABIs on
# top of each other.
: ${__GLIBC_CC:=$(tc-getCC ${CTARGET_OPT:-${CTARGET}})}
export __GLIBC_CC CC="${__GLIBC_CC} ${!VAR}"
}
just_headers() {
is_crosscompile && use crosscompile_opts_headers-only
}
glibc_banner() {
local b="Gentoo ${PVR}"
[[ -n ${SNAP_VER} ]] && b+=" snapshot ${SNAP_VER}"
[[ -n ${BRANCH_UPDATE} ]] && b+=" branch ${BRANCH_UPDATE}"
[[ -n ${PATCH_VER} ]] && ! use vanilla && b+=" p${PATCH_VER}"
echo "${b}"
}

View File

@ -0,0 +1,27 @@
# Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/sys-libs/glibc/files/eblits/pkg_postinst.eblit,v 1.2 2012/04/15 20:04:44 vapier Exp $
eblit-glibc-pkg_postinst() {
# nothing to do if just installing headers
just_headers && return
if ! tc-is-cross-compiler && [[ -x ${ROOT}/usr/sbin/iconvconfig ]] ; then
# Generate fastloading iconv module configuration file.
"${ROOT}"/usr/sbin/iconvconfig --prefix="${ROOT}"
fi
if ! is_crosscompile && [[ ${ROOT} == "/" ]] ; then
# Reload init ... if in a chroot or a diff init package, ignore
# errors from this step #253697
/sbin/telinit U 2>/dev/null
# if the host locales.gen contains no entries, we'll install everything
local locale_list="${ROOT}etc/locale.gen"
if [[ -z $(locale-gen --list --config "${locale_list}") ]] ; then
ewarn "Generating all locales; edit /etc/locale.gen to save time/space"
locale_list="${ROOT}usr/share/i18n/SUPPORTED"
fi
locale-gen -j $(makeopts_jobs) --config "${locale_list}"
fi
}

View File

@ -0,0 +1,60 @@
# Copyright 1999-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/sys-libs/glibc/files/eblits/pkg_preinst.eblit,v 1.11 2013/06/29 03:22:32 heroxbd Exp $
# Simple test to make sure our new glibc isnt completely broken.
# Make sure we don't test with statically built binaries since
# they will fail. Also, skip if this glibc is a cross compiler.
glibc_sanity_check() {
cd / #228809
# We enter ${D} so to avoid trouble if the path contains
# special characters; for instance if the path contains the
# colon character (:), then the linker will try to split it
# and look for the libraries in an unexpected place. This can
# lead to unsafe code execution if the generated prefix is
# within a world-writable directory.
# (e.g. /var/tmp/portage:${HOSTNAME})
pushd "${ED}"/$(get_libdir) >/dev/null
local x striptest
for x in date env ls true uname ; do
x=$(type -p ${x})
[[ -z ${x} || ${x} != ${EPREFIX}/* ]] && continue
striptest=$(LC_ALL="C" file -L ${x} 2>/dev/null) || continue
[[ ${striptest} == *"statically linked"* ]] && continue
./ld-*.so --library-path . ${x} > /dev/null \
|| die "simple run test (${x}) failed"
done
popd >/dev/null
}
eblit-glibc-pkg_preinst() {
# nothing to do if just installing headers
just_headers && return
# prepare /etc/ld.so.conf.d/ for files
mkdir -p "${EROOT}"/etc/ld.so.conf.d
# Default /etc/hosts.conf:multi to on for systems with small dbs.
if [[ $(wc -l < "${EROOT}"/etc/hosts) -lt 1000 ]] ; then
sed -i '/^multi off/s:off:on:' "${ED}"/etc/host.conf
elog "Defaulting /etc/host.conf:multi to on"
fi
[[ ${ROOT} != "/" ]] && return 0
[[ -d ${D}/$(get_libdir) ]] || return 0
glibc_sanity_check
# Make sure devpts is mounted correctly for use w/out setuid pt_chown.
if in_iuse suid && ! use suid ; then
if awk '$3 == "devpts" && $4 ~ /[, ]gid=5[, ]/ { exit 1 }' /proc/mounts ; then
eerror "In order to use glibc with USE=-suid, you must make sure that"
eerror "you have devpts mounted at /dev/pts with the gid=5 option."
eerror "Openrc should do this for you, so you should check /etc/fstab"
eerror "and make sure you do not have any invalid settings there."
die "mount & fix your /dev/pts settings"
fi
fi
}

View File

@ -0,0 +1,122 @@
# Copyright 1999-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/sys-libs/glibc/files/eblits/pkg_setup.eblit,v 1.11 2013/06/29 03:22:32 heroxbd Exp $
glibc_compile_test() {
local ret save_cflags=${CFLAGS}
CFLAGS+=" $1"
shift
pushd "${T}" >/dev/null
rm -f glibc-test*
printf '%b' "$*" > glibc-test.c
emake -s glibc-test
ret=$?
popd >/dev/null
CFLAGS=${save_cflags}
return ${ret}
}
glibc_run_test() {
local ret
if [[ ${EMERGE_FROM} == "binary" ]] ; then
# ignore build failures when installing a binary package #324685
glibc_compile_test "" "$@" 2>/dev/null || return 0
else
if ! glibc_compile_test "" "$@" ; then
ewarn "Simple build failed ... assuming this is desired #324685"
return 0
fi
fi
pushd "${T}" >/dev/null
./glibc-test
ret=$?
rm -f glibc-test*
popd >/dev/null
return ${ret}
}
eblit-glibc-pkg_setup() {
# prevent native builds from downgrading ... maybe update to allow people
# to change between diff -r versions ? (2.3.6-r4 -> 2.3.6-r2)
if [[ ${ROOT} == "/" ]] && [[ ${CBUILD} == ${CHOST} ]] && [[ ${CHOST} == ${CTARGET} ]] ; then
if has_version '>'${CATEGORY}/${PF} ; then
eerror "Sanity check to keep you from breaking your system:"
eerror " Downgrading glibc is not supported and a sure way to destruction"
die "aborting to save your system"
fi
if ! glibc_run_test '#include <pwd.h>\nint main(){return getpwuid(0)==0;}\n'
then
eerror "Your patched vendor kernel is broken. You need to get an"
eerror "update from whoever is providing the kernel to you."
eerror "http://sourceware.org/bugzilla/show_bug.cgi?id=5227"
eerror "http://bugs.gentoo.org/262698"
die "keeping your system alive, say thank you"
fi
if ! glibc_run_test '#include <unistd.h>\n#include <sys/syscall.h>\nint main(){return syscall(1000)!=-1;}\n'
then
eerror "Your old kernel is broken. You need to update it to"
eerror "a newer version as syscall(<bignum>) will break."
eerror "http://bugs.gentoo.org/279260"
die "keeping your system alive, say thank you"
fi
fi
# users have had a chance to phase themselves, time to give em the boot
if [[ -e ${EROOT}/etc/locale.gen ]] && [[ -e ${EROOT}/etc/locales.build ]] ; then
eerror "You still haven't deleted ${EROOT}/etc/locales.build."
eerror "Do so now after making sure ${EROOT}/etc/locale.gen is kosher."
die "lazy upgrader detected"
fi
if [[ ${CTARGET} == i386-* ]] ; then
eerror "i386 CHOSTs are no longer supported."
eerror "Chances are you don't actually want/need i386."
eerror "Please read http://www.gentoo.org/doc/en/change-chost.xml"
die "please fix your CHOST"
fi
if [[ -e /proc/xen ]] && [[ $(tc-arch) == "x86" ]] && ! is-flag -mno-tls-direct-seg-refs ; then
ewarn "You are using Xen but don't have -mno-tls-direct-seg-refs in your CFLAGS."
ewarn "This will result in a 50% performance penalty when running with a 32bit"
ewarn "hypervisor, which is probably not what you want."
fi
use hardened && ! gcc-specs-pie && \
ewarn "PIE hardening not applied, as your compiler doesn't default to PIE"
# Make sure host system is up to date #394453
if has_version '<sys-libs/glibc-2.13' && \
[[ -n $(scanelf -qys__guard -F'#s%F' "${EROOT}"/lib*/l*-*.so) ]]
then
ebegin "Scanning system for __guard to see if you need to rebuild first ..."
local files=$(
scanelf -qys__guard -F'#s%F' \
"${EROOT}"/*bin/ \
"${EROOT}"/lib* \
"${EROOT}"/usr/*bin/ \
"${EROOT}"/usr/lib* | \
egrep -v \
-e "^${EROOT}/lib.*/(libc|ld)-2.*.so$" \
-e "^${EROOT}/sbin/(ldconfig|sln)$"
)
[[ -z ${files} ]]
if ! eend $? ; then
eerror "Your system still has old SSP __guard symbols. You need to"
eerror "rebuild all the packages that provide these files first:"
eerror "${files}"
die "old __guard detected"
fi
fi
}

View File

@ -0,0 +1,254 @@
# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/sys-libs/glibc/files/eblits/src_compile.eblit,v 1.37 2014/01/17 06:23:22 vapier Exp $
glibc_do_configure() {
local myconf=()
einfo "Configuring GLIBC for $1"
# set addons
pushd "${S}" > /dev/null
local ADDONS=$(echo */configure | sed \
-e 's:/configure::g' \
-e 's:\(linuxthreads\|nptl\|rtkaio\|glibc-compat\)\( \|$\)::g' \
-e 's: \+$::' \
-e 's! !,!g' \
-e 's!^!,!' \
-e '/^,\*$/d')
[[ -d ports ]] && ADDONS="${ADDONS},ports"
popd > /dev/null
myconf+=( $(use_enable hardened stackguard-randomization) )
if has_version '<sys-libs/glibc-2.13' ; then
myconf+=( --enable-old-ssp-compat )
fi
[[ $(tc-is-softfloat) == "yes" ]] && myconf+=( --without-fp )
if [[ $1 == "linuxthreads" ]] ; then
if want_tls ; then
myconf+=( --with-tls )
if ! want__thread || use glibc-compat20 || [[ ${LT_KER_VER} == 2.[02].* ]] ; then
myconf+=( --without-__thread )
else
myconf+=( --with-__thread )
fi
else
myconf+=( --without-tls --without-__thread )
fi
myconf+=( --disable-sanity-checks )
myconf+=( --enable-add-ons="linuxthreads${ADDONS}" )
myconf+=( --enable-kernel=${LT_KER_VER} )
elif [[ $1 == "nptl" ]] ; then
myconf+=( --enable-add-ons="nptl${ADDONS}" )
myconf+=( --enable-kernel=${NPTL_KERN_VER} )
else
die "invalid pthread option"
fi
# Since SELinux support is only required for nscd, only enable it if:
# 1. USE selinux
# 2. only for the primary ABI on multilib systems
# 3. Not a crosscompile
if ! is_crosscompile && use selinux ; then
if use multilib || has_multilib_profile ; then
if is_final_abi ; then
myconf+=( --with-selinux )
else
myconf+=( --without-selinux )
fi
else
myconf+=( --with-selinux )
fi
else
myconf+=( --without-selinux )
fi
myconf+=(
--without-cvs
--enable-bind-now
--build=${CBUILD_OPT:-${CBUILD}}
--host=${CTARGET_OPT:-${CTARGET}}
$(use_enable profile)
$(use_with gd)
--with-headers=$(alt_build_headers)
--prefix=/usr
--libdir=/usr/$(get_libdir)
--mandir=/usr/share/man
--infodir=/usr/share/info
--libexecdir=/usr/$(get_libdir)/misc/glibc
--with-bugurl=http://bugs.gentoo.org/
--with-pkgversion="$(glibc_banner)"
$(use_multiarch || echo --disable-multi-arch)
--enable-obsolete-rpc
$(in_iuse systemtap && use_enable systemtap)
$(in_iuse nscd && use_enable nscd)
${EXTRA_ECONF}
)
# There is no configure option for this and we need to export it
# since the glibc build will re-run configure on itself
export libc_cv_slibdir=/$(get_libdir)
# We take care of patching our binutils to use both hash styles,
# and many people like to force gnu hash style only, so disable
# this overriding check. #347761
export libc_cv_hashstyle=no
# Overtime, generating info pages can be painful. So disable this for
# versions older than the latest stable to avoid the issue (this ver
# should be updated from time to time). #464394 #465816
if ! version_is_at_least 2.17 ; then
export ac_cv_prog_MAKEINFO=:
fi
local GBUILDDIR=${WORKDIR}/build-${ABI}-${CTARGET}-$1
mkdir -p "${GBUILDDIR}"
cd "${GBUILDDIR}"
set -- "${S}"/configure "${myconf[@]}"
echo "$@"
"$@" || die "failed to configure glibc"
# ia64 static cross-compilers are a pita in so much that they
# can't produce static ELFs (as the libgcc.a is broken). so
# disable building of the programs for those targets if it
# doesn't work.
# XXX: We could turn this into a compiler test, but ia64 is
# the only one that matters, so this should be fine for now.
if is_crosscompile && [[ ${CTARGET} == ia64* ]] ; then
sed -i '1i+link-static = touch $@' config.make
fi
}
toolchain-glibc_src_compile() {
echo
local v
for v in ABI CBUILD CHOST CTARGET CBUILD_OPT CTARGET_OPT CC {AS,C,CPP,CXX,LD}FLAGS ; do
einfo " $(printf '%15s' ${v}:) ${!v}"
done
export CC=$(tc-getCC ${CTARGET})
# Glibc does not work with gold (for various reasons) #269274.
if $(tc-getLD ${CTARGET}) --version | grep -q 'GNU gold' ; then
local d="${T}/bfd-linker"
mkdir -p "${d}"
ln -sf $(which ${CTARGET}-ld.bfd) "${d}"/ld
CC+=" -B${d}"
fi
einfo " $(printf '%15s' 'Manual CC:') ${CC}"
echo
if want_linuxthreads ; then
glibc_do_configure linuxthreads
emake || die "make for ${ABI} failed"
fi
if want_nptl ; then
# ... and then do the optional nptl build
unset LD_ASSUME_KERNEL
glibc_do_configure nptl
emake || die "make for ${ABI} failed"
fi
}
toolchain-glibc_headers_compile() {
local GBUILDDIR=${WORKDIR}/build-${ABI}-${CTARGET}-headers
mkdir -p "${GBUILDDIR}"
cd "${GBUILDDIR}"
# if we don't have a compiler yet, we cant really test it now ...
# hopefully they don't affect header geneation, so let's hope for
# the best here ...
local v vars=(
ac_cv_header_cpuid_h=yes
libc_cv_{386,390,alpha,arm,hppa,ia64,mips,{powerpc,sparc}{,32,64},sh,x86_64}_tls=yes
libc_cv_asm_cfi_directives=yes
libc_cv_broken_visibility_attribute=no
libc_cv_gcc___thread=yes
libc_cv_mlong_double_128=yes
libc_cv_mlong_double_128ibm=yes
libc_cv_ppc_machine=yes
libc_cv_ppc_rel16=yes
libc_cv_predef_{fortify_source,stack_protector}=no
libc_cv_visibility_attribute=yes
libc_cv_z_combreloc=yes
libc_cv_z_execstack=yes
libc_cv_z_initfirst=yes
libc_cv_z_nodelete=yes
libc_cv_z_nodlopen=yes
libc_cv_z_relro=yes
libc_mips_abi=${ABI}
libc_mips_float=$([[ $(tc-is-softfloat) == "yes" ]] && echo soft || echo hard)
)
einfo "Forcing cached settings:"
for v in "${vars[@]}" ; do
einfo " ${v}"
export ${v}
done
# Pick out the correct location for build headers
local ports="" myconf=()
[[ -d ${S}/ports ]] && ports=",ports"
myconf+=(
--disable-sanity-checks
--enable-hacker-mode
--enable-add-ons=nptl${ports}
--without-cvs
--enable-bind-now
--build=${CBUILD_OPT:-${CBUILD}}
--host=${CTARGET_OPT:-${CTARGET}}
--with-headers=$(alt_build_headers)
--prefix=/usr
${EXTRA_ECONF}
)
# Nothing is compiled here which would affect the headers for the target.
# so forcing CC/CFLAGS is sane. unless you dont have `gcc`. then i
# dont care :p.
set -- "${S}"/configure "${myconf[@]}"
CC=gcc \
CFLAGS="-O1 -pipe" \
CPPFLAGS="-U_FORTIFY_SOURCE" \
LDFLAGS="" \
"$@" || die "failed to configure glibc"
}
eblit-glibc-src_compile() {
if is_crosscompile ; then
export \
libc_cv_c_cleanup=yes \
libc_cv_forced_unwind=yes
fi
if just_headers ; then
export ABI=default
toolchain-glibc_headers_compile
return
fi
setup_env
if [[ -z ${OABI} ]] ; then
local abilist=""
if has_multilib_profile ; then
abilist=$(get_install_abis)
elif is_crosscompile || tc-is-cross-compiler ; then
abilist=${DEFAULT_ABI}
fi
einfo "Building glibc for ABIs: ${abilist}"
if [[ -n ${abilist} ]] ; then
OABI=${ABI}
for ABI in ${abilist} ; do
export ABI
src_compile
done
ABI=${OABI}
unset OABI
return 0
fi
fi
toolchain-glibc_src_compile
}

View File

@ -0,0 +1,274 @@
# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/sys-libs/glibc/files/eblits/src_install.eblit,v 1.33 2014/01/17 07:45:29 vapier Exp $
toolchain-glibc_src_install() {
local GBUILDDIR
if want_linuxthreads ; then
GBUILDDIR=${WORKDIR}/build-${ABI}-${CTARGET}-linuxthreads
else
GBUILDDIR=${WORKDIR}/build-${ABI}-${CTARGET}-nptl
fi
local install_root="${D}$(alt_prefix)"
if want_linuxthreads ; then
cd "${WORKDIR}"/build-${ABI}-${CTARGET}-linuxthreads
einfo "Installing GLIBC ${ABI} with linuxthreads ..."
else
cd "${WORKDIR}"/build-${ABI}-${CTARGET}-nptl
einfo "Installing GLIBC ${ABI} with NPTL ..."
fi
emake install_root="${install_root}" install || die
if want_linuxthreads && want_nptl ; then
einfo "Installing NPTL to $(alt_libdir)/tls/..."
cd "${WORKDIR}"/build-${ABI}-${CTARGET}-nptl
dodir $(alt_libdir)/tls $(alt_usrlibdir)/nptl
local l src_lib
for l in libc libm librt libpthread libthread_db ; do
# take care of shared lib first ...
l=${l}.so
if [[ -e ${l} ]] ; then
src_lib=${l}
else
src_lib=$(eval echo */${l})
fi
cp -a ${src_lib} "${ED}"$(alt_libdir)/tls/${l} || die "copying nptl ${l}"
fperms a+rx $(alt_libdir)/tls/${l}
dosym ${l} $(alt_libdir)/tls/$(scanelf -qSF'%S#F' ${src_lib})
# then grab the linker script or the symlink ...
if [[ -L ${ED}$(alt_usrlibdir)/${l} ]] ; then
dosym $(alt_libdir)/tls/${l} $(alt_usrlibdir)/nptl/${l}
else
sed \
-e "s:/${l}:/tls/${l}:g" \
-e "s:/${l/%.so/_nonshared.a}:/nptl/${l/%.so/_nonshared.a}:g" \
"${ED}"$(alt_usrlibdir)/${l} > "${ED}"$(alt_usrlibdir)/nptl/${l}
fi
# then grab the static lib ...
src_lib=${src_lib/%.so/.a}
[[ ! -e ${src_lib} ]] && src_lib=${src_lib/%.a/_pic.a}
cp -a ${src_lib} "${ED}"$(alt_usrlibdir)/nptl/ || die "copying nptl ${src_lib}"
src_lib=${src_lib/%.a/_nonshared.a}
if [[ -e ${src_lib} ]] ; then
cp -a ${src_lib} "${ED}"$(alt_usrlibdir)/nptl/ || die "copying nptl ${src_lib}"
fi
done
# use the nptl linker instead of the linuxthreads one as the linuxthreads
# one may lack TLS support and that can be really bad for business
cp -a elf/ld.so "${ED}"$(alt_libdir)/$(scanelf -qSF'%S#F' elf/ld.so) || die "copying nptl interp"
fi
# We'll take care of the cache ourselves
rm -f "${ED}"/etc/ld.so.cache
# Everything past this point just needs to be done once ...
is_final_abi || return 0
# Make sure the non-native interp can be found on multilib systems even
# if the main library set isn't installed into the right place. Maybe
# we should query the active gcc for info instead of hardcoding it ?
local i ldso_abi ldso_name
local ldso_abi_list=(
# x86
amd64 /lib64/ld-linux-x86-64.so.2
x32 /libx32/ld-linux-x32.so.2
x86 /lib/ld-linux.so.2
# mips
o32 /lib/ld.so.1
n32 /lib32/ld.so.1
n64 /lib64/ld.so.1
# powerpc
ppc /lib/ld.so.1
ppc64 /lib64/ld64.so.1
# s390
s390 /lib/ld.so.1
s390x /lib/ld64.so.1
# sparc
sparc32 /lib/ld-linux.so.2
sparc64 /lib64/ld-linux.so.2
)
case $(tc-endian) in
little)
ldso_abi_list+=(
# arm
arm64 /lib/ld-linux-aarch64.so.1
)
;;
big)
ldso_abi_list+=(
# arm
arm64 /lib/ld-linux-aarch64_be.so.1
)
;;
esac
if [[ ${SYMLINK_LIB} == "yes" ]] && [[ ! -e ${ED}/$(alt_prefix)/lib ]] ; then
dosym $(get_abi_LIBDIR ${DEFAULT_ABI}) $(alt_prefix)/lib
fi
for (( i = 0; i < ${#ldso_abi_list[@]}; i += 2 )) ; do
ldso_abi=${ldso_abi_list[i]}
has ${ldso_abi} $(get_install_abis) || continue
ldso_name="$(alt_prefix)${ldso_abi_list[i+1]}"
if [[ ! -L ${D}/${ldso_name} && ! -e ${D}/${ldso_name} ]] ; then
dosym ../$(get_abi_LIBDIR ${ldso_abi})/${ldso_name##*/} ${ldso_name}
fi
done
# With devpts under Linux mounted properly, we do not need the pt_chown
# binary to be setuid. This is because the default owners/perms will be
# exactly what we want.
if in_iuse suid && ! use suid ; then
find "${D}" -name pt_chown -exec chmod -s {} +
fi
#################################################################
# EVERYTHING AFTER THIS POINT IS FOR NATIVE GLIBC INSTALLS ONLY #
# Make sure we install some symlink hacks so that when we build
# a 2nd stage cross-compiler, gcc finds the target system
# headers correctly. See gcc/doc/gccinstall.info
if is_crosscompile ; then
# We need to make sure that /lib and /usr/lib always exists.
# gcc likes to use relative paths to get to its multilibs like
# /usr/lib/../lib64/. So while we don't install any files into
# /usr/lib/, we do need it to exist.
cd "${ED}"$(alt_libdir)/..
[[ -e lib ]] || mkdir lib
cd "${ED}"$(alt_usrlibdir)/..
[[ -e lib ]] || mkdir lib
dosym usr/include $(alt_prefix)/sys-include
return 0
fi
# Files for Debian-style locale updating
dodir /usr/share/i18n
sed \
-e "/^#/d" \
-e "/SUPPORTED-LOCALES=/d" \
-e "s: \\\\::g" -e "s:/: :g" \
"${S}"/localedata/SUPPORTED > "${ED}"/usr/share/i18n/SUPPORTED \
|| die "generating /usr/share/i18n/SUPPORTED failed"
cd "${WORKDIR}"/extra/locale
dosbin locale-gen || die
doman *.[0-8]
insinto /etc
doins locale.gen || die
# Make sure all the ABI's can find the locales and so we only
# have to generate one set
local a
keepdir /usr/$(get_libdir)/locale
for a in $(get_install_abis) ; do
if [[ ! -e ${ED}/usr/$(get_abi_LIBDIR ${a})/locale ]] ; then
dosym /usr/$(get_libdir)/locale /usr/$(get_abi_LIBDIR ${a})/locale
fi
done
cd "${S}"
# Install misc network config files
insinto /etc
doins nscd/nscd.conf posix/gai.conf nss/nsswitch.conf || die
doins "${WORKDIR}"/extra/etc/*.conf || die
if ! in_iuse nscd || use nscd ; then
doinitd "${WORKDIR}"/extra/etc/nscd || die
local nscd_args=(
-e "s:@PIDFILE@:$(strings "${ED}"/usr/sbin/nscd | grep nscd.pid):"
)
version_is_at_least 2.16 || nscd_args+=( -e 's: --foreground : :' )
sed -i "${nscd_args[@]}" "${ED}"/etc/init.d/nscd
if [[ $(type -t systemd_dounit) == "function" ]] ; then
systemd_dounit "${FILESDIR}"/nscd.service || die
systemd_newtmpfilesd "${FILESDIR}"/nscd.tmpfilesd nscd.conf || die
fi
else
# Do this since extra/etc/*.conf above might have nscd.conf.
rm -f "${ED}"/etc/nscd.conf
fi
echo 'LDPATH="include ld.so.conf.d/*.conf"' > "${T}"/00glibc
doenvd "${T}"/00glibc || die
for d in BUGS ChangeLog* CONFORMANCE FAQ NEWS NOTES PROJECTS README* ; do
[[ -s ${d} ]] && dodoc ${d}
done
# Prevent overwriting of the /etc/localtime symlink. We'll handle the
# creation of the "factory" symlink in pkg_postinst().
rm -f "${ED}"/etc/localtime
}
toolchain-glibc_headers_install() {
local GBUILDDIR=${WORKDIR}/build-${ABI}-${CTARGET}-headers
cd "${GBUILDDIR}"
emake install_root="${D}$(alt_prefix)" install-headers || die
if ! version_is_at_least 2.16 ; then
insinto $(alt_headers)/bits
doins bits/stdio_lim.h || die
fi
insinto $(alt_headers)/gnu
doins "${S}"/include/gnu/stubs.h || die "doins include gnu"
# Make sure we install the sys-include symlink so that when
# we build a 2nd stage cross-compiler, gcc finds the target
# system headers correctly. See gcc/doc/gccinstall.info
dosym usr/include /usr/${CTARGET}/sys-include
}
src_strip() {
# gdb is lame and requires some debugging information to remain in
# libpthread, so we need to strip it by hand. libthread_db makes no
# sense stripped as it is only used when debugging.
local pthread=$(has splitdebug ${FEATURES} && echo "libthread_db" || echo "lib{pthread,thread_db}")
env \
-uRESTRICT \
CHOST=${CTARGET} \
STRIP_MASK="/*/{,tls/}${pthread}*" \
prepallstrip
# if user has stripping enabled and does not have split debug turned on,
# then leave the debugging sections in libpthread.
if ! has nostrip ${FEATURES} && ! has splitdebug ${FEATURES} ; then
${STRIP:-${CTARGET}-strip} --strip-debug "${ED}"/*/libpthread-*.so
fi
}
eblit-glibc-src_install() {
if just_headers ; then
export ABI=default
toolchain-glibc_headers_install
return
fi
setup_env
if [[ -z ${OABI} ]] ; then
local abilist=""
if has_multilib_profile ; then
abilist=$(get_install_abis)
einfo "Installing multilib glibc for ABIs: ${abilist}"
elif is_crosscompile || tc-is-cross-compiler ; then
abilist=${DEFAULT_ABI}
fi
if [[ -n ${abilist} ]] ; then
OABI=${ABI}
for ABI in ${abilist} ; do
export ABI
eblit-glibc-src_install
done
ABI=${OABI}
unset OABI
src_strip
return 0
fi
fi
toolchain-glibc_src_install
[[ -z ${OABI} ]] && src_strip
}

View File

@ -0,0 +1,56 @@
# Copyright 1999-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/sys-libs/glibc/files/eblits/src_test.eblit,v 1.5 2013/04/11 20:42:56 vapier Exp $
toolchain-glibc_src_test() {
cd "${WORKDIR}"/build-${ABI}-${CTARGET}-$1 || die "cd build-${ABI}-${CTARGET}-$1"
unset LD_ASSUME_KERNEL
emake -j1 check && return 0
einfo "make check failed - re-running with --keep-going to get the rest of the results"
emake -j1 -k check
ewarn "make check failed for ${ABI}-${CTARGET}-$1"
return 1
}
eblit-glibc-src_test() {
local ret=0
setup_env
_maybe_die() {
if [[ -n ${OABI} ]] ; then
return ${ret}
elif [[ ${ret} -ne 0 ]] ; then
die "tests failed"
fi
}
# give tests more time to complete
export TIMEOUTFACTOR=5
if [[ -z ${OABI} ]] && has_multilib_profile ; then
OABI=${ABI}
einfo "Testing multilib glibc for ABIs: $(get_install_abis)"
for ABI in $(get_install_abis) ; do
export ABI
einfo " Testing ${ABI} glibc"
eblit-glibc-src_test
: $(( ret += $? ))
done
ABI=${OABI}
unset OABI
_maybe_die
return
fi
local t
for t in linuxthreads nptl ; do
if want_${t} ; then
toolchain-glibc_src_test ${t}
: $(( ret += $? ))
fi
done
_maybe_die
return
}

View File

@ -0,0 +1,179 @@
# Copyright 1999-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/sys-libs/glibc/files/eblits/src_unpack.eblit,v 1.24 2013/09/28 22:07:57 vapier Exp $
int_to_KV() {
local version=$1 major minor micro
major=$((version / 65536))
minor=$(((version % 65536) / 256))
micro=$((version % 256))
echo ${major}.${minor}.${micro}
}
eend_KV() {
[[ $(KV_to_int $1) -ge $(KV_to_int $2) ]]
eend $?
}
get_kheader_version() {
printf '#include <linux/version.h>\nLINUX_VERSION_CODE\n' | \
$(tc-getCPP ${CTARGET}) -I "${EPREFIX}/$(alt_build_headers)" - | \
tail -n 1
}
check_nptl_support() {
# don't care about the compiler here as we arent using it
just_headers && return
local run_kv build_kv want_kv
run_kv=$(int_to_KV $(get_KV))
build_kv=$(int_to_KV $(get_kheader_version))
want_kv=${NPTL_KERN_VER}
ebegin "Checking gcc for __thread support"
if ! eend $(want__thread ; echo $?) ; then
echo
eerror "Could not find a gcc that supports the __thread directive!"
eerror "Please update your binutils/gcc and try again."
die "No __thread support in gcc!"
fi
if ! is_crosscompile && ! tc-is-cross-compiler ; then
# Building fails on an non-supporting kernel
ebegin "Checking kernel version (${run_kv} >= ${want_kv})"
if ! eend_KV ${run_kv} ${want_kv} ; then
echo
eerror "You need a kernel of at least ${want_kv} for NPTL support!"
die "Kernel version too low!"
fi
fi
ebegin "Checking linux-headers version (${build_kv} >= ${want_kv})"
if ! eend_KV ${build_kv} ${want_kv} ; then
echo
eerror "You need linux-headers of at least ${want_kv} for NPTL support!"
die "linux-headers version too low!"
fi
}
unpack_pkg() {
local a=${PN}
[[ -n ${SNAP_VER} ]] && a="${a}-${RELEASE_VER}"
[[ -n $1 ]] && a="${a}-$1"
if [[ -n ${SNAP_VER} ]] ; then
a="${a}-${SNAP_VER}"
else
if [[ -n $2 ]] ; then
a="${a}-$2"
else
a="${a}-${RELEASE_VER}"
fi
fi
if has ${a}.tar.xz ${A} ; then
unpacker ${a}.tar.xz
else
unpack ${a}.tar.bz2
fi
[[ -n $1 ]] && { mv ${a} $1 || die ; }
}
toolchain-glibc_src_unpack() {
# Check NPTL support _before_ we unpack things to save some time
want_nptl && check_nptl_support
if [[ -n ${EGIT_REPO_URIS} ]] ; then
local i d
for ((i=0; i<${#EGIT_REPO_URIS[@]}; ++i)) ; do
EGIT_REPO_URI=${EGIT_REPO_URIS[$i]}
EGIT_SOURCEDIR=${EGIT_SOURCEDIRS[$i]}
git-2_src_unpack
done
else
unpack_pkg
fi
cd "${S}"
touch locale/C-translit.h #185476 #218003
[[ -n ${LT_VER} ]] && unpack_pkg linuxthreads ${LT_VER}
[[ -n ${PORTS_VER} ]] && unpack_pkg ports ${PORTS_VER}
[[ -n ${LIBIDN_VER} ]] && unpack_pkg libidn
if [[ -n ${PATCH_VER} ]] ; then
cd "${WORKDIR}"
unpack glibc-${RELEASE_VER}-patches-${PATCH_VER}.tar.bz2
# pull out all the addons
local d
for d in extra/*/configure ; do
d=${d%/configure}
[[ -d ${S}/${d} ]] && die "${d} already exists in \${S}"
mv "${d}" "${S}" || die "moving ${d} failed"
done
fi
# XXX: We should do the branchupdate, before extracting the manpages and
# infopages else it does not help much (mtimes change if there is a change
# to them with branchupdate)
if [[ -n ${BRANCH_UPDATE} ]] ; then
cd "${S}"
epatch "${DISTDIR}"/glibc-${RELEASE_VER}-branch-update-${BRANCH_UPDATE}.patch.bz2
# Snapshot date patch
einfo "Patching version to display snapshot date ..."
sed -i -e "s:\(#define RELEASE\).*:\1 \"${BRANCH_UPDATE}\":" version.h
fi
# tag, glibc is it
cd "${S}"
if ! version_is_at_least 2.17 ; then
[[ -e csu/Banner ]] && die "need new banner location"
glibc_banner > csu/Banner
fi
if [[ -n ${PATCH_VER} ]] && ! use vanilla ; then
cd "${S}"
EPATCH_MULTI_MSG="Applying Gentoo Glibc Patchset ${RELEASE_VER}-${PATCH_VER} ..." \
EPATCH_EXCLUDE=${GLIBC_PATCH_EXCLUDE} \
EPATCH_SUFFIX="patch" \
ARCH=$(tc-arch) \
epatch "${WORKDIR}"/patches
fi
if just_headers ; then
if [[ -e ports/sysdeps/mips/preconfigure ]] ; then
# mips peeps like to screw with us. if building headers,
# we don't have a real compiler, so we can't let them
# insert -mabi on us.
sed -i '/CPPFLAGS=.*-mabi/s|.*|:|' ports/sysdeps/mips/preconfigure || die
find ports/sysdeps/mips/ -name Makefile -exec sed -i '/^CC.*-mabi=/s:-mabi=.*:-D_MIPS_SZPTR=32:' {} +
fi
fi
epatch_user
gnuconfig_update
}
eblit-glibc-src_unpack() {
setup_env
toolchain-glibc_src_unpack
# Glibc is stupid sometimes, and doesn't realize that with a
# static C-Only gcc, -lgcc_eh doesn't exist.
# http://sourceware.org/ml/libc-alpha/2003-09/msg00100.html
# http://sourceware.org/ml/libc-alpha/2005-02/msg00042.html
# But! Finally fixed in recent versions:
# http://sourceware.org/ml/libc-alpha/2012-05/msg01865.html
if ! version_is_at_least 2.16 ; then
echo 'int main(){}' > "${T}"/gcc_eh_test.c
if ! $(tc-getCC ${CTARGET}) "${T}"/gcc_eh_test.c -lgcc_eh 2>/dev/null ; then
sed -i -e 's:-lgcc_eh::' Makeconfig || die "sed gcc_eh"
fi
fi
cd "${WORKDIR}"
find . -type f '(' -size 0 -o -name "*.orig" ')' -exec rm -f {} \;
find . -name configure -exec touch {} \;
# Fix permissions on some of the scripts
chmod u+x "${S}"/scripts/*.sh
}

View File

@ -0,0 +1,64 @@
#!/sbin/runscript
# Copyright 1999-2005 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/sys-libs/glibc/files/nscd,v 1.7 2007/02/23 12:09:39 uberlord Exp $
depend() {
use dns ldap net slapd
}
checkconfig() {
if [ ! -d /var/run/nscd ] ; then
mkdir -p /var/run/nscd
chmod 755 /var/run/nscd
fi
if [ -z "${NSCD_PERMS_OK}" ] && [ "$(stat -c %a /var/run/nscd)" != "755" ] ; then
echo ""
ewarn "nscd run dir is not world readable, you should reset the perms:"
ewarn "chmod 755 /var/run/nscd"
ewarn "chmod a+rw /var/run/nscd/socket"
echo ""
ewarn "To disable this warning, set 'NSCD_PERMS_OK' in /etc/conf.d/nscd"
echo ""
fi
}
start() {
checkconfig
ebegin "Starting Name Service Cache Daemon"
local secure=`while read curline ; do
table=${curline%:*}
entries=${curline##$table:}
table=${table%%[^a-z]*}
case $table in
passwd*|group*|hosts)
for entry in $entries ; do
case $entry in
nisplus*)
/usr/sbin/nscd_nischeck $table || \
/echo "-S $table,yes"
;;
esac
done
;;
esac
done < /etc/nsswitch.conf`
local pidfile="$(strings /usr/sbin/nscd | grep nscd.pid)"
mkdir -p "$(dirname ${pidfile})"
save_options pidfile "${pidfile}"
start-stop-daemon --start --quiet \
--exec /usr/sbin/nscd --pidfile "${pidfile}" \
-- $secure
eend $?
}
stop() {
local pidfile="$(get_options pidfile)"
[ -n "${pidfile}" ] && pidfile="--pidfile ${pidfile}"
ebegin "Shutting down Name Service Cache Daemon"
start-stop-daemon --stop --quiet --exec /usr/sbin/nscd ${pidfile}
eend $?
}
# vim:ts=4

View File

@ -0,0 +1,15 @@
[Unit]
Description=Name Service Cache Daemon
After=network.target
[Service]
ExecStart=/usr/sbin/nscd -F
ExecStop=/usr/sbin/nscd --shutdown
ExecReload=/usr/sbin/nscd -i passwd
ExecReload=/usr/sbin/nscd -i group
ExecReload=/usr/sbin/nscd -i hosts
ExecReload=/usr/sbin/nscd -i services
Restart=always
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,4 @@
# Configuration to create /run/nscd directory
# Used as part of systemd's tmpfiles
d /run/nscd 0755 root root

View File

@ -0,0 +1,24 @@
# /etc/nsswitch.conf:
# $Header: /var/cvsroot/gentoo-x86/sys-libs/glibc/files/nsswitch.conf,v 1.1 2005/05/17 00:52:41 vapier Exp $
passwd: compat
shadow: compat
group: compat
# passwd: db files nis
# shadow: db files nis
# group: db files nis
hosts: files dns
networks: files dns
services: db files
protocols: db files
rpc: db files
ethers: db files
netmasks: files
netgroup: files
bootparams: files
automount: files
aliases: files

View File

@ -0,0 +1 @@
glibc-2.17.ebuild

View File

@ -0,0 +1,227 @@
# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/sys-libs/glibc/glibc-2.17.ebuild,v 1.31 2014/01/31 18:22:06 vapier Exp $
inherit eutils versionator toolchain-funcs flag-o-matic gnuconfig multilib systemd unpacker multiprocessing
DESCRIPTION="GNU libc6 (also called glibc2) C library"
HOMEPAGE="http://www.gnu.org/software/libc/libc.html"
LICENSE="LGPL-2.1+ BSD HPND ISC inner-net rc PCRE"
KEYWORDS="alpha amd64 arm arm64 hppa ia64 m68k ~mips ppc ppc64 s390 sh ~sparc x86"
RESTRICT="strip" # strip ourself #46186
EMULTILIB_PKG="true"
# Configuration variables
RELEASE_VER=""
case ${PV} in
9999*)
EGIT_REPO_URIS="git://sourceware.org/git/glibc.git"
EGIT_SOURCEDIRS="${S}"
inherit git-2
;;
*)
RELEASE_VER=${PV}
;;
esac
PATCH_VER="8" # Gentoo patchset
NPTL_KERN_VER=${NPTL_KERN_VER:-"2.6.16"} # min kernel version nptl requires
IUSE="debug gd hardened multilib nscd selinux systemtap profile suid vanilla crosscompile_opts_headers-only"
# Here's how the cross-compile logic breaks down ...
# CTARGET - machine that will target the binaries
# CHOST - machine that will host the binaries
# CBUILD - machine that will build the binaries
# If CTARGET != CHOST, it means you want a libc for cross-compiling.
# If CHOST != CBUILD, it means you want to cross-compile the libc.
# CBUILD = CHOST = CTARGET - native build/install
# CBUILD != (CHOST = CTARGET) - cross-compile a native build
# (CBUILD = CHOST) != CTARGET - libc for cross-compiler
# CBUILD != CHOST != CTARGET - cross-compile a libc for a cross-compiler
# For install paths:
# CHOST = CTARGET - install into /
# CHOST != CTARGET - install into /usr/CTARGET/
export CBUILD=${CBUILD:-${CHOST}}
export CTARGET=${CTARGET:-${CHOST}}
if [[ ${CTARGET} == ${CHOST} ]] ; then
if [[ ${CATEGORY} == cross-* ]] ; then
export CTARGET=${CATEGORY#cross-}
fi
fi
[[ ${CTARGET} == hppa* ]] && NPTL_KERN_VER=${NPTL_KERN_VER/2.6.16/2.6.20}
is_crosscompile() {
[[ ${CHOST} != ${CTARGET} ]]
}
# Why SLOT 2.2 you ask yourself while sippin your tea ?
# Everyone knows 2.2 > 0, duh.
SLOT="2.2"
# General: We need a new-enough binutils/gcc to match upstream baseline.
# arch: we need to make sure our binutils/gcc supports TLS.
DEPEND=">=app-misc/pax-utils-0.1.10
!<sys-apps/sandbox-1.6
!<sys-apps/portage-2.1.2
selinux? ( sys-libs/libselinux )"
RDEPEND="!sys-kernel/ps3-sources
selinux? ( sys-libs/libselinux )
!sys-libs/nss-db"
if [[ ${CATEGORY} == cross-* ]] ; then
DEPEND+=" !crosscompile_opts_headers-only? (
>=${CATEGORY}/binutils-2.20
>=${CATEGORY}/gcc-4.3
)"
[[ ${CATEGORY} == *-linux* ]] && DEPEND+=" ${CATEGORY}/linux-headers"
else
DEPEND+="
>=sys-devel/binutils-2.20
>=sys-devel/gcc-4.3
virtual/os-headers
!vanilla? ( >=sys-libs/timezone-data-2012c )"
RDEPEND+="
vanilla? ( !sys-libs/timezone-data )
!vanilla? ( sys-libs/timezone-data )"
fi
SRC_URI=$(
upstream_uris() {
echo mirror://gnu/glibc/$1 ftp://sourceware.org/pub/glibc/{releases,snapshots}/$1 mirror://gentoo/$1
}
gentoo_uris() {
local devspace="HTTP~vapier/dist/URI HTTP~azarah/glibc/URI"
devspace=${devspace//HTTP/http://dev.gentoo.org/}
echo mirror://gentoo/$1 ${devspace//URI/$1}
}
[[ -z ${EGIT_REPO_URIS} ]] && upstream_uris ${P}.tar.xz
[[ -n ${PATCH_VER} ]] && gentoo_uris ${P}-patches-${PATCH_VER}.tar.bz2
)
# eblit-include [--skip] <function> [version]
eblit-include() {
local skipable=false
[[ $1 == "--skip" ]] && skipable=true && shift
[[ $1 == pkg_* ]] && skipable=true
local e v func=$1 ver=$2
[[ -z ${func} ]] && die "Usage: eblit-include <function> [version]"
for v in ${ver:+-}${ver} -${PVR} -${PV} "" ; do
e="${FILESDIR}/eblits/${func}${v}.eblit"
if [[ -e ${e} ]] ; then
source "${e}"
return 0
fi
done
${skipable} && return 0
die "Could not locate requested eblit '${func}' in ${FILESDIR}/eblits/"
}
# eblit-run-maybe <function>
# run the specified function if it is defined
eblit-run-maybe() {
[[ $(type -t "$@") == "function" ]] && "$@"
}
# eblit-run <function> [version]
# aka: src_unpack() { eblit-run src_unpack ; }
eblit-run() {
eblit-include --skip common "${*:2}"
eblit-include "$@"
eblit-run-maybe eblit-$1-pre
eblit-${PN}-$1
eblit-run-maybe eblit-$1-post
}
src_unpack() { eblit-run src_unpack ; }
src_compile() { eblit-run src_compile ; }
src_test() { eblit-run src_test ; }
src_install() { eblit-run src_install ; }
# FILESDIR might not be available during binpkg install
for x in setup {pre,post}inst ; do
e="${FILESDIR}/eblits/pkg_${x}.eblit"
if [[ -e ${e} ]] ; then
. "${e}"
eval "pkg_${x}() { eblit-run pkg_${x} ; }"
fi
done
eblit-src_unpack-pre() {
GLIBC_PATCH_EXCLUDE+=" 6600_mips_librt-mips.patch" #456912
}
eblit-src_unpack-post() {
if use hardened ; then
cd "${S}"
einfo "Patching to get working PIE binaries on PIE (hardened) platforms"
gcc-specs-pie && epatch "${FILESDIR}"/2.17/glibc-2.17-hardened-pie.patch
epatch "${FILESDIR}"/2.10/glibc-2.10-hardened-configure-picdefault.patch
epatch "${FILESDIR}"/2.10/glibc-2.10-hardened-inittls-nosysenter.patch
einfo "Installing Hardened Gentoo SSP and FORTIFY_SOURCE handler"
cp -f "${FILESDIR}"/2.6/glibc-2.6-gentoo-stack_chk_fail.c \
debug/stack_chk_fail.c || die
cp -f "${FILESDIR}"/2.10/glibc-2.10-gentoo-chk_fail.c \
debug/chk_fail.c || die
if use debug ; then
# When using Hardened Gentoo stack handler, have smashes dump core for
# analysis - debug only, as core could be an information leak
# (paranoia).
sed -i \
-e '/^CFLAGS-backtrace.c/ iCFLAGS-stack_chk_fail.c = -DSSP_SMASH_DUMPS_CORE' \
debug/Makefile \
|| die "Failed to modify debug/Makefile for debug stack handler"
sed -i \
-e '/^CFLAGS-backtrace.c/ iCFLAGS-chk_fail.c = -DSSP_SMASH_DUMPS_CORE' \
debug/Makefile \
|| die "Failed to modify debug/Makefile for debug fortify handler"
fi
# Build nscd with ssp-all
sed -i \
-e 's:-fstack-protector$:-fstack-protector-all:' \
nscd/Makefile \
|| die "Failed to ensure nscd builds with ssp-all"
fi
}
eblit-pkg_preinst-post() {
if [[ ${CTARGET} == arm* ]] ; then
# Backwards compat support for renaming hardfp ldsos #417287
local oldso='/lib/ld-linux.so.3'
local nldso='/lib/ld-linux-armhf.so.3'
if [[ -e ${D}${nldso} ]] ; then
if scanelf -qRyi "${ROOT}$(alt_prefix)"/*bin/ | grep -s "^${oldso}" ; then
ewarn "Symlinking old ldso (${oldso}) to new ldso (${nldso})."
ewarn "Please rebuild all packages using this old ldso as compat"
ewarn "support will be dropped in the future."
ln -s "${nldso##*/}" "${D}$(alt_prefix)${oldso}"
fi
fi
fi
}
# CoreOS tweaks:
# - drop host.conf and gai.conf
# - move/symlink nsswitch.conf and rpc.
# These are moving to baselayout+usrfiles and glibc shouldn't conflict
eblit-src_install-post() {
dodir /usr/share/glibc
mv "${D}"/etc/{nsswitch.conf,rpc} "${D}"/usr/share/glibc || die
rm "${D}"/etc/{gai.conf,host.conf} || die
}
eblit-pkg_postinst-post() {
local sym
for sym in nsswitch.conf rpc ; do
if [ ! -f "${ROOT}/etc/${sym}" ]; then
ln -s "../usr/share/glibc/${sym}" "${ROOT}/etc/${sym}" || die
fi
done
}