From: Michael Tremer Date: Sun, 7 Feb 2010 14:54:08 +0000 (+0100) Subject: glibc: Copy patch files into repository. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b2ec3c8a437494d3238a29287d0a47d957d5ed2b;p=ipfire-3.x.git glibc: Copy patch files into repository. --- diff --git a/pkgs/core/glibc/glibc.nm b/pkgs/core/glibc/glibc.nm index bcac591d0..9819c0d55 100644 --- a/pkgs/core/glibc/glibc.nm +++ b/pkgs/core/glibc/glibc.nm @@ -57,75 +57,68 @@ OPTIMIZED_KERNEL = 2.6.18 PKG_OBJECTS += $(THISAPP).tar.bz2 -# Support for PT_PaX markings: -PKG_PATCHES += $(THISAPP)-pt_pax-1.patch - -# This patch adds the strlcpy and strlcat functions and manual pages to Glibc. -# A paper written about these functions is available here: -# http://www.courtesan.com/todd/papers/strlcpy.html. The Glibc project has -# refused to add these functions, and that mail tread starts here: -# http://sources.redhat.com/ml/libc-alpha/2000-08/msg00052.html. Linus Torvalds -# has added a similar function to the Linux kernel, and that mail thread is -# here: http://lwn.net/Articles/33814/. The strlcpy() and strlcat() functions -# are replacements for strncpy() and strncat(). The controversy of these -# functions is that strlcpy() and strlcat() copy the source data to the -# destination buffer until the destination is full, and discards the rest of -# the data if there is any. This means that these functions will never -# overflow. The basis for the Glibc team's refusal to add these functions is -# that they silently hide programing errors, and they have a higher performance -# hit than strncpy() and strncat(). These functions should not be needed in a -# perfect world, but were invented to deal with the real world. Many packages -# will use these functions if they are found, such as Perl and many BLFS -# packages. These functions do reduce buffer overflows, and so they are -# recommended. After installing this patch no other effort is needed to use it. -# Packages will use autotools to detect whether they are available or not: -PKG_PATCHES += $(THISAPP)-strlcpy_strlcat-1.patch - -# The asprintf(3) and vasprintf(3) functions are GNU extentions, not defined -# by C or Posix standards. In Glibc these functions leave (char **strp) undefined -# after an error. This patch resets (char **strp) to NULL after an error, for -# sanity. -PKG_PATCHES += $(THISAPP)-asprintf_reset2null-1.patch - -# This patch adds the issetugid() function, which is a front-end to the -# __libc_enable_secure() dynamic linker private function. This function -# reports whether the program is running with matching real and effective -# ID's, or not, to determine whether the program is running with set-uid or -# set-gid privileges. Many packages will search for issetugid() and use it if -# found, such as Ncurses. This is safer than allowing each program to -# determine privileges itself because it is tested at a lower level which is -# not manipulatable by the user. Apply this patch with the following command: -PKG_PATCHES += $(THISAPP)-issetugid-1.patch - -# The next patch modifies the localedef program so it does not use GCC -# Trampoline code (http://gcc.gnu.org/onlinedocs/gccint/Trampolines.html), -# which relies on an executable stack to run. Without this patch the localedef -# program will be killed if it is run on a kernel with PaX memory protection. -# See http://pax.grsecurity.net/docs/pageexec.txt and -# http://pax.grsecurity.net/docs/segmexec.txt for more information: -PKG_PATCHES += $(THISAPP)-localedef_trampoline-1.patch - -# This patch resticts the environment, particularly with setuid programs: -#PKG_PATCHES += $(THISAPP)-sanitize_env.patch - -# The patch modifies __gen_tempname(), used by the mk*temp()/tmpnam() family -# of functions, to use /dev/urandom instead of hp-timing, gettimeofday(), or -# getpid(): -PKG_PATCHES += $(THISAPP)-mktemp_urandom.patch - -# The res_randomid() function is a pseudo-random number generator, using -# getpid() for entropy. See: http://www.openbsd.org/advisories/res_random.txt -# for the vulnerability. This patch uses /dev/urandom instead: -PKG_PATCHES += $(THISAPP)-res_randomid.patch - -# This patch does a check on the buffer size of res_* functions: -PKG_PATCHES += $(THISAPP)-resolv_response_length.patch - -PKG_PATCHES += $(THISAPP)-undefine-__i686.patch -PKG_PATCHES += $(THISAPP)-arc4random.patch -PKG_PATCHES += $(THISAPP)-hardened-configure-picdefault.patch -PKG_PATCHES += $(THISAPP)-hardened-inittls-nosysenter.patch -PKG_PATCHES += $(THISAPP)-hardened-pie.patch +# $(THISAPP)-pt_pax-1.patch - Support for PT_PaX markings. + +# $(THISAPP)-strlcpy_strlcat-1.patch +# This patch adds the strlcpy and strlcat functions and manual pages to Glibc. +# A paper written about these functions is available here: +# http://www.courtesan.com/todd/papers/strlcpy.html. The Glibc project has +# refused to add these functions, and that mail tread starts here: +# http://sources.redhat.com/ml/libc-alpha/2000-08/msg00052.html. Linus Torvalds +# has added a similar function to the Linux kernel, and that mail thread is +# here: http://lwn.net/Articles/33814/. The strlcpy() and strlcat() functions +# are replacements for strncpy() and strncat(). The controversy of these +# functions is that strlcpy() and strlcat() copy the source data to the +# destination buffer until the destination is full, and discards the rest of +# the data if there is any. This means that these functions will never +# overflow. The basis for the Glibc team's refusal to add these functions is +# that they silently hide programing errors, and they have a higher performance +# hit than strncpy() and strncat(). These functions should not be needed in a +# perfect world, but were invented to deal with the real world. Many packages +# will use these functions if they are found, such as Perl and many BLFS +# packages. These functions do reduce buffer overflows, and so they are +# recommended. After installing this patch no other effort is needed to use it. +# Packages will use autotools to detect whether they are available or not. + +# $(THISAPP)-asprintf_reset2null-1.patch +# The asprintf(3) and vasprintf(3) functions are GNU extentions, not defined +# by C or Posix standards. In Glibc these functions leave (char **strp) undefined +# after an error. This patch resets (char **strp) to NULL after an error, for +# sanity. + +# $(THISAPP)-issetugid-1.patch +# This patch adds the issetugid() function, which is a front-end to the +# __libc_enable_secure() dynamic linker private function. This function +# reports whether the program is running with matching real and effective +# ID's, or not, to determine whether the program is running with set-uid or +# set-gid privileges. Many packages will search for issetugid() and use it if +# found, such as Ncurses. This is safer than allowing each program to +# determine privileges itself because it is tested at a lower level which is +# not manipulatable by the user. Apply this patch with the following command: + +# $(THISAPP)-localedef_trampoline-1.patch +# The next patch modifies the localedef program so it does not use GCC +# Trampoline code (http://gcc.gnu.org/onlinedocs/gccint/Trampolines.html), +# which relies on an executable stack to run. Without this patch the localedef +# program will be killed if it is run on a kernel with PaX memory protection. +# See http://pax.grsecurity.net/docs/pageexec.txt and +# http://pax.grsecurity.net/docs/segmexec.txt for more information. + +# $(THISAPP)-sanitize_env.patch +# This patch resticts the environment, particularly with setuid programs. + +# $(THISAPP)-mktemp_urandom.patch +# The patch modifies __gen_tempname(), used by the mk*temp()/tmpnam() family +# of functions, to use /dev/urandom instead of hp-timing, gettimeofday(), or +# getpid(): + +# $(THISAPP)-res_randomid.patch +# The res_randomid() function is a pseudo-random number generator, using +# getpid() for entropy. See: http://www.openbsd.org/advisories/res_random.txt +# for the vulnerability. This patch uses /dev/urandom instead. + +# $(THISAPP)-resolv_response_length.patch +# This patch does a check on the buffer size of res_* functions. ############################################################################### # Installation Details diff --git a/pkgs/core/glibc/patches/glibc-2.10.1-arc4random.patch b/pkgs/core/glibc/patches/glibc-2.10.1-arc4random.patch new file mode 100644 index 000000000..c877c8c86 --- /dev/null +++ b/pkgs/core/glibc/patches/glibc-2.10.1-arc4random.patch @@ -0,0 +1,541 @@ +Submitted By: Robert Connolly (ashes) +Date: 2006-01-01 +Initial Package Version: 2.3.6 +Upstream Status: Not submitted +Origin: http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/crypt/arc4random.c +Description: This patch adds the arc4random() and arc4randomII() functions +to Glibc, and hooks so mktemp(3) can use arc4randomII(). + +Also see: +http://www.linuxfromscratch.org/hlfs/ +http://www.linuxfromscratch.org/hints/downloads/files/entropy.txt + +diff -Naur glibc-2.3.6.orig/manual/arc4random.3 glibc-2.3.6/manual/arc4random.3 +--- glibc-2.3.6.orig/manual/arc4random.3 1970-01-01 00:00:00.000000000 +0000 ++++ glibc-2.3.6/manual/arc4random.3 2006-01-01 07:48:48.000000000 +0000 +@@ -0,0 +1,74 @@ ++.TH ARC4RANDOM 3 "February 11, 2005" ++.SH NAME ++arc4random - arc4 random number generator ++.SH SYNOPSIS ++.nf ++.B #include ++.sp ++.I u_int32_t ++.B arc4random(void); ++.sp ++.I u_int32_t ++.B arc4randomII(void); ++.fi ++.SH DESCRIPTION ++The \fBarc4random()\fP function generates a pseudo-random number using the ++ARC4 cipher key stream generator. ARCFOUR uses 8*8 8 bit S-Boxes, and can ++be in about (2**1700) states. ++ ++The \fBarc4random()\fP function is seeded automatically from /dev/urandom, ++or from sysctl \fBurandom\fP if /dev/urandom is not accessible (chroot), or from ++sysctl random.uuid if sysctl \fBurandom\fP is not accessible. \fBgettimeofday(2)\fP ++is always included when initializing the state of \fBarc4random()\fP, this makes ++it impossible to generate the same random sequence twice. \fBarc4random()\fP ++is intended to be safe to use with encryption software to provide entropy. ++ ++The \fBarc4randomII()\fP function is identical to \fBarc4random()\fP except ++that \fBarc4randomII()\fP is seeded automatically from /dev/erandom, and ++sysctl erandom. \fBarc4randomII()\fP is NOT intended for cryptography, but is ++ideal for \fBmktemp(3)\fP, and other functions with a short lifespan. ++\fBarc4randomII()\fP and erandom do not consume any kernel entropy. ++ ++Sysctl urandom, and erandom require a modified kernel. See: ++http://www.linuxfromscratch.org/hlfs/ ++ ++.SH EXAMPLES ++.TP ++Return a random number between 0 and 100. ++.sp ++arc4random() % 100; ++.TP ++Return any random number. ++.sp ++arc4random(); ++.TP ++.nf ++Sample program; this will display a number between 0 and 65536. ++ ++#include ++#include ++ ++int main(void) { ++ int random_number; ++ random_number = arc4random() % 65536; ++ printf("%d\n", random_number); ++ return 0; ++} ++.fi ++.SH "SEE ALSO" ++.BR random (3), ++.BR gettimeofday (2), ++.BR mktemp (3) ++ ++.SH HISTORY ++An algorithm called RC4 was designed by RSA Data Security, Inc. It was ++considered a trade secret, but not trademarked. Because it was a trade ++secret, it obviously could not be patented. A clone of this was posted ++anonymously to USENET and confirmed to be equivalent by several sources ++who had access to the original cipher. Because of the trade secret situation, ++RSA Data Security, Inc. can do nothing about the release of the ++ARC4 algorithm. Since RC4 used to be a trade secret, the cipher is now ++referred to as ARC4 (Another RC4). ++ ++These functions first appeared in OpenBSD 2.1. ++ +diff -Naur glibc-2.3.6.orig/stdlib/Makefile glibc-2.3.6/stdlib/Makefile +--- glibc-2.3.6.orig/stdlib/Makefile 2005-02-16 11:23:58.000000000 +0000 ++++ glibc-2.3.6/stdlib/Makefile 2006-01-01 07:48:48.000000000 +0000 +@@ -27,7 +27,7 @@ + + routines := \ + atof atoi atol atoll \ +- abort \ ++ abort arc4random arc4randomII \ + bsearch qsort msort \ + getenv putenv setenv secure-getenv \ + exit on_exit atexit cxa_atexit cxa_finalize old_atexit \ +diff -Naur glibc-2.3.6.orig/stdlib/Versions glibc-2.3.6/stdlib/Versions +--- glibc-2.3.6.orig/stdlib/Versions 2004-05-03 21:25:53.000000000 +0000 ++++ glibc-2.3.6/stdlib/Versions 2006-01-01 07:50:28.000000000 +0000 +@@ -11,6 +11,8 @@ + + # a* + a64l; abort; abs; atexit; atof; atoi; atol; atoll; ++ arc4random_stir; arc4random_addrandom; arc4random; ++ arc4random_stirII; arc4random_addrandomII; arc4randomII; + + # b* + bsearch; +diff -Naur glibc-2.3.6.orig/stdlib/arc4random.c glibc-2.3.6/stdlib/arc4random.c +--- glibc-2.3.6.orig/stdlib/arc4random.c 1970-01-01 00:00:00.000000000 +0000 ++++ glibc-2.3.6/stdlib/arc4random.c 2006-01-01 07:48:48.000000000 +0000 +@@ -0,0 +1,205 @@ ++/* ++ * Arc4 random number generator for OpenBSD. ++ * Copyright 1996 David Mazieres . ++ * ++ * Modification and redistribution in source and binary forms is ++ * permitted provided that due credit is given to the author and the ++ * OpenBSD project by leaving this copyright notice intact. ++ */ ++ ++/* ++ * This code is derived from section 17.1 of Applied Cryptography, ++ * second edition, which describes a stream cipher allegedly ++ * compatible with RSA Labs "RC4" cipher (the actual description of ++ * which is a trade secret). The same algorithm is used as a stream ++ * cipher called "arcfour" in Tatu Ylonen's ssh package. ++ * ++ * Here the stream cipher has been modified always to include the time ++ * when initializing the state. That makes it impossible to ++ * regenerate the same random sequence twice, so this can't be used ++ * for encryption, but will generate good random numbers. ++ * ++ * RC4 is a registered trademark of RSA Laboratories. ++ */ ++ ++/* ++ * Modified by Robert Connolly from OpenBSD lib/libc/crypt/arc4random.c v1.11. ++ * This is arc4random(3) using urandom. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef __GNUC__ ++#define inline __inline ++#else /* !__GNUC__ */ ++#define inline ++#endif /* !__GNUC__ */ ++ ++struct arc4_stream { ++ u_int8_t i; ++ u_int8_t j; ++ u_int8_t s[256]; ++}; ++ ++static int rs_initialized; ++static struct arc4_stream rs; ++static pid_t arc4_stir_pid; ++ ++static inline u_int8_t arc4_getbyte(struct arc4_stream *); ++ ++static inline void ++arc4_init(struct arc4_stream *as) ++{ ++ int n; ++ ++ for (n = 0; n < 256; n++) ++ as->s[n] = n; ++ as->i = 0; ++ as->j = 0; ++} ++ ++static inline void ++arc4_addrandom(struct arc4_stream *as, u_char *dat, int datlen) ++{ ++ int n; ++ u_int8_t si; ++ ++ as->i--; ++ for (n = 0; n < 256; n++) { ++ as->i = (as->i + 1); ++ si = as->s[as->i]; ++ as->j = (as->j + si + dat[n % datlen]); ++ as->s[as->i] = as->s[as->j]; ++ as->s[as->j] = si; ++ } ++ as->j = as->i; ++} ++ ++static void ++arc4_stir(struct arc4_stream *as) ++{ ++ int n, fd; ++ struct { ++ struct timeval tv; ++ u_int rnd[(128 - sizeof(struct timeval)) / sizeof(u_int)]; ++ } rdat; ++ ++ gettimeofday(&rdat.tv, NULL); ++ ++ /* /dev/urandom is a multithread interface, sysctl is not. */ ++ /* Try to use /dev/urandom before sysctl. */ ++ fd = open("/dev/urandom", O_RDONLY); ++ if (fd != -1) { ++ read(fd, rdat.rnd, sizeof(rdat.rnd)); ++ close(fd); ++ } ++ ++#if defined(SYSCTL_URANDOM) ++ else { ++ /* /dev/urandom failed? Maybe we're in a chroot. */ ++ int mib[]={CTL_KERN, KERN_RANDOM, RANDOM_URANDOM}; ++ u_int i; ++ size_t len; ++ ++ for (i = 0; i < sizeof(rdat.rnd) / sizeof(u_int); i ++) { ++ len = sizeof(u_int); ++ if (sysctl(mib, 3, &rdat.rnd[i], &len, NULL, 0) == -1) ++ break; ++ } ++ if (i < sizeof(rdat.rnd) / 4) { ++ /* Sysctl urandom failed? Maybe we're running a vanilla kernel. */ ++ mib[2] = RANDOM_UUID; ++ for (i = 0; i < sizeof(rdat.rnd) / sizeof(u_int); i ++) { ++ len = sizeof(u_int); ++ if (sysctl(mib, 3, &rdat.rnd[i], &len, NULL, 0) == -1) ++ break; ++ } ++ } ++ } ++#endif ++ ++ arc4_stir_pid = getpid(); ++ /* ++ * Time to give up. If no entropy could be found then we will just ++ * use gettimeofday. ++ */ ++ arc4_addrandom(as, (void *)&rdat, sizeof(rdat)); ++ ++ /* ++ * Discard early keystream, as per recommendations in: ++ * http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps ++ * We discard 256 words. A long word is 4 bytes. ++ */ ++ for (n = 0; n < 256 * 4; n ++) ++ arc4_getbyte(as); ++} ++ ++static inline u_int8_t ++arc4_getbyte(struct arc4_stream *as) ++{ ++ u_int8_t si, sj; ++ ++ as->i = (as->i + 1); ++ si = as->s[as->i]; ++ as->j = (as->j + si); ++ sj = as->s[as->j]; ++ as->s[as->i] = sj; ++ as->s[as->j] = si; ++ return (as->s[(si + sj) & 0xff]); ++} ++ ++static inline u_int32_t ++arc4_getword(struct arc4_stream *as) ++{ ++ u_int32_t val; ++ val = arc4_getbyte(as) << 24; ++ val |= arc4_getbyte(as) << 16; ++ val |= arc4_getbyte(as) << 8; ++ val |= arc4_getbyte(as); ++ return val; ++} ++ ++void ++arc4random_stir(void) ++{ ++ if (!rs_initialized) { ++ arc4_init(&rs); ++ rs_initialized = 1; ++ } ++ arc4_stir(&rs); ++} ++ ++void ++arc4random_addrandom(u_char *dat, int datlen) ++{ ++ if (!rs_initialized) ++ arc4random_stir(); ++ arc4_addrandom(&rs, dat, datlen); ++} ++ ++u_int32_t ++arc4random(void) ++{ ++ if (!rs_initialized || arc4_stir_pid != getpid()) ++ arc4random_stir(); ++ return arc4_getword(&rs); ++} ++ ++#if 0 ++/*-------- Test code --------*/ ++#include ++#include ++ ++int main(void) { ++ int random_number; ++ random_number = arc4random() % 65536; ++ printf("A random number between 0 and 65536 is %d\n", random_number); ++ return 0; ++} ++#endif +diff -Naur glibc-2.3.6.orig/stdlib/arc4randomII.c glibc-2.3.6/stdlib/arc4randomII.c +--- glibc-2.3.6.orig/stdlib/arc4randomII.c 1970-01-01 00:00:00.000000000 +0000 ++++ glibc-2.3.6/stdlib/arc4randomII.c 2006-01-01 07:48:48.000000000 +0000 +@@ -0,0 +1,196 @@ ++/* ++ * Arc4 random number generator for OpenBSD. ++ * Copyright 1996 David Mazieres . ++ * ++ * Modification and redistribution in source and binary forms is ++ * permitted provided that due credit is given to the author and the ++ * OpenBSD project by leaving this copyright notice intact. ++ */ ++ ++/* ++ * This code is derived from section 17.1 of Applied Cryptography, ++ * second edition, which describes a stream cipher allegedly ++ * compatible with RSA Labs "RC4" cipher (the actual description of ++ * which is a trade secret). The same algorithm is used as a stream ++ * cipher called "arcfour" in Tatu Ylonen's ssh package. ++ * ++ * Here the stream cipher has been modified always to include the time ++ * when initializing the state. That makes it impossible to ++ * regenerate the same random sequence twice, so this can't be used ++ * for encryption, but will generate good random numbers. ++ * ++ * RC4 is a registered trademark of RSA Laboratories. ++ */ ++ ++/* ++ * Modified by Robert Connolly from OpenBSD lib/libc/crypt/arc4random.c v1.11. ++ * This is arc4randomII(3) using erandom. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef __GNUC__ ++#define inline __inline ++#else /* !__GNUC__ */ ++#define inline ++#endif /* !__GNUC__ */ ++ ++struct arc4_streamII { ++ u_int8_t i; ++ u_int8_t j; ++ u_int8_t s[256]; ++}; ++ ++static int rs_initializedII; ++static struct arc4_streamII rs; ++static pid_t arc4_stir_pidII; ++ ++static inline u_int8_t arc4_getbyteII(struct arc4_streamII *); ++ ++static inline void ++arc4_initII(struct arc4_streamII *as) ++{ ++ int n; ++ ++ for (n = 0; n < 256; n++) ++ as->s[n] = n; ++ as->i = 0; ++ as->j = 0; ++} ++ ++static inline void ++arc4_addrandomII(struct arc4_streamII *as, u_char *dat, int datlen) ++{ ++ int n; ++ u_int8_t si; ++ ++ as->i--; ++ for (n = 0; n < 256; n++) { ++ as->i = (as->i + 1); ++ si = as->s[as->i]; ++ as->j = (as->j + si + dat[n % datlen]); ++ as->s[as->i] = as->s[as->j]; ++ as->s[as->j] = si; ++ } ++ as->j = as->i; ++} ++ ++static void ++arc4_stirII(struct arc4_streamII *as) ++{ ++ int n, fd; ++ struct { ++ struct timeval tv; ++ u_int rnd[(128 - sizeof(struct timeval)) / sizeof(u_int)]; ++ } rdat; ++ ++ gettimeofday(&rdat.tv, NULL); ++ ++ /* /dev/urandom is a multithread interface, sysctl is not. */ ++ /* Try to use /dev/urandom before sysctl. */ ++ fd = open("/dev/erandom", O_RDONLY); ++ if (fd != -1) { ++ read(fd, rdat.rnd, sizeof(rdat.rnd)); ++ close(fd); ++ } ++ ++#if defined(SYSCTL_ERANDOM) ++ else { ++ /* /dev/urandom failed? Maybe we're in a chroot. */ ++ int mib[]={CTL_KERN, KERN_RANDOM, RANDOM_ERANDOM}; ++ u_int i; ++ size_t len; ++ ++ for (i = 0; i < sizeof(rdat.rnd) / sizeof(u_int); i++) { ++ len = sizeof(u_int); ++ if (sysctl(mib, 3, &rdat.rnd[i], &len, NULL, 0) == -1) ++ break; ++ } ++ } ++#endif ++ ++ arc4_stir_pidII = getpid(); ++ /* ++ * Time to give up. If no entropy could be found then we will just ++ * use gettimeofday. ++ */ ++ arc4_addrandomII(as, (void *)&rdat, sizeof(rdat)); ++ ++ /* ++ * Discard early keystream, as per recommendations in: ++ * http://www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps ++ * We discard 256 words. A long word is 4 bytes. ++ */ ++ for (n = 0; n < 256 * 4; n ++) ++ arc4_getbyteII(as); ++} ++ ++static inline u_int8_t ++arc4_getbyteII(struct arc4_streamII *as) ++{ ++ u_int8_t si, sj; ++ ++ as->i = (as->i + 1); ++ si = as->s[as->i]; ++ as->j = (as->j + si); ++ sj = as->s[as->j]; ++ as->s[as->i] = sj; ++ as->s[as->j] = si; ++ return (as->s[(si + sj) & 0xff]); ++} ++ ++static inline u_int32_t ++arc4_getwordII(struct arc4_streamII *as) ++{ ++ u_int32_t val; ++ val = arc4_getbyteII(as) << 24; ++ val |= arc4_getbyteII(as) << 16; ++ val |= arc4_getbyteII(as) << 8; ++ val |= arc4_getbyteII(as); ++ return val; ++} ++ ++void ++arc4random_stirII(void) ++{ ++ if (!rs_initializedII) { ++ arc4_initII(&rs); ++ rs_initializedII = 1; ++ } ++ arc4_stirII(&rs); ++} ++ ++void ++arc4random_addrandomII(u_char *dat, int datlen) ++{ ++ if (!rs_initializedII) ++ arc4random_stirII(); ++ arc4_addrandomII(&rs, dat, datlen); ++} ++ ++u_int32_t ++arc4randomII(void) ++{ ++ if (!rs_initializedII || arc4_stir_pidII != getpid()) ++ arc4random_stirII(); ++ return arc4_getwordII(&rs); ++} ++ ++#if 0 ++/*-------- Test code --------*/ ++#include ++#include ++ ++int main(void) { ++ int random_number; ++ random_number = arc4randomII() % 65536; ++ printf("A random number between 0 and 65536 is %d\n", random_number); ++ return 0; ++} ++#endif +diff -Naur glibc-2.3.6.orig/stdlib/stdlib.h glibc-2.3.6/stdlib/stdlib.h +--- glibc-2.3.6.orig/stdlib/stdlib.h 2005-07-18 01:15:30.000000000 +0000 ++++ glibc-2.3.6/stdlib/stdlib.h 2006-01-01 07:48:48.000000000 +0000 +@@ -572,6 +572,15 @@ + extern int lcong48_r (unsigned short int __param[7], + struct drand48_data *__buffer) + __THROW __nonnull ((1, 2)); ++ ++#define LIBC_HAS_ARC4RANDOM ++u_int32_t arc4random(void); ++void arc4random_stir(void); ++void arc4random_addrandom(unsigned char *, int); ++u_int32_t arc4randomII(void); ++void arc4random_stirII(void); ++void arc4random_addrandomII(unsigned char *, int); ++ + # endif /* Use misc. */ + #endif /* Use SVID or X/Open. */ diff --git a/pkgs/core/glibc/patches/glibc-2.10.1-asprintf_reset2null-1.patch b/pkgs/core/glibc/patches/glibc-2.10.1-asprintf_reset2null-1.patch new file mode 100644 index 000000000..60dd425cc --- /dev/null +++ b/pkgs/core/glibc/patches/glibc-2.10.1-asprintf_reset2null-1.patch @@ -0,0 +1,59 @@ +Submitted By: Robert Connolly (ashes) +Date: 2007-05-07 +Initial Package Version: 2.5 +Upstream Status: Submitted +http://sourceware.org/ml/libc-alpha/2004-05/msg00067.html +http://sourceware.org/ml/libc-alpha/2004-06/msg00007.html +Origin: Alt-Linux / Dmitry V. Levin +Description: + +The asprintf(3) and vasprintf(3) functions are GNU extentions, not defined +by C or Posix standards. In Glibc these functions leave (char **strp) undefined +after an error. This patch resets (char **strp) to NULL after an error, for +sanity. + +This patch, and the behavior it sets, was reviewed and discussed on the Glibc +mailing list, and appeared to be accepted, and then it looks like it was +forgotten about. + +2004-06-03 Dmitry V. Levin + + * libio/vasprintf.c (_IO_vasprintf): Reset the result pointer + to NULL on any error. + * manual/stdio.texi: Reflect the change in asprintf API. + +--- glibc-2.5.orig/libio/vasprintf.c ++++ glibc-2.5/libio/vasprintf.c +@@ -50,7 +50,10 @@ _IO_vasprintf (result_ptr, format, args) + we know we will never seek on the stream. */ + string = (char *) malloc (init_string_size); + if (string == NULL) +- return -1; ++ { ++ *result_ptr = NULL; ++ return -1; ++ } + #ifdef _IO_MTSAFE_IO + sf._sbf._f._lock = NULL; + #endif +@@ -64,6 +67,7 @@ #endif + if (ret < 0) + { + free (sf._sbf._f._IO_buf_base); ++ *result_ptr = NULL; + return ret; + } + /* Only use realloc if the size we need is of the same (binary) +--- glibc-2.5.orig/manual/stdio.texi ++++ glibc-2.5/manual/stdio.texi +@@ -2398,7 +2398,9 @@ to the newly allocated string at that lo + + The return value is the number of characters allocated for the buffer, or + less than zero if an error occurred. Usually this means that the buffer +-could not be allocated. ++could not be allocated, and the value of @var{ptr} in this situation is ++implementation-dependent (in glibc, @var{ptr} will be set to the null ++pointer, but this behavior should not be relied upon). + + Here is how to use @code{asprintf} to get the same result as the + @code{snprintf} example, but more easily: diff --git a/pkgs/core/glibc/patches/glibc-2.10.1-hardened-configure-picdefault.patch b/pkgs/core/glibc/patches/glibc-2.10.1-hardened-configure-picdefault.patch new file mode 100644 index 000000000..19f25443d --- /dev/null +++ b/pkgs/core/glibc/patches/glibc-2.10.1-hardened-configure-picdefault.patch @@ -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 + +--- glibc-2.10.1/configure.in ++++ glibc-2.10.1/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.*]) +--- glibc-2.10.1/configure ++++ glibc-2.10.1/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.* diff --git a/pkgs/core/glibc/patches/glibc-2.10.1-hardened-inittls-nosysenter.patch b/pkgs/core/glibc/patches/glibc-2.10.1-hardened-inittls-nosysenter.patch new file mode 100644 index 000000000..ce9c907fa --- /dev/null +++ b/pkgs/core/glibc/patches/glibc-2.10.1-hardened-inittls-nosysenter.patch @@ -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 + +--- glibc-2.10.1/csu/libc-start.c ++++ glibc-2.10.1/csu/libc-start.c +@@ -28,6 +28,7 @@ + extern int __libc_multiple_libcs; + + #include ++#include + #ifndef SHARED + # include + 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 (); +--- glibc-2.10.1/csu/libc-tls.c ++++ glibc-2.10.1/csu/libc-tls.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + + #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 +--- glibc-2.10.1/misc/sbrk.c ++++ glibc-2.10.1/misc/sbrk.c +@@ -18,6 +18,7 @@ + + #include + #include ++#include + + /* 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) + { +--- glibc-2.10.1/sysdeps/unix/sysv/linux/i386/brk.c ++++ glibc-2.10.1/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) + { +--- glibc-2.10.1/sysdeps/unix/sysv/linux/i386/sysdep.h ++++ glibc-2.10.1/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" diff --git a/pkgs/core/glibc/patches/glibc-2.10.1-hardened-pie.patch b/pkgs/core/glibc/patches/glibc-2.10.1-hardened-pie.patch new file mode 100644 index 000000000..65693d6af --- /dev/null +++ b/pkgs/core/glibc/patches/glibc-2.10.1-hardened-pie.patch @@ -0,0 +1,39 @@ +Change link commands for glibc executables to build PIEs + +Patch by Kevin F. Quinn + +--- glibc-2.10.1/Makeconfig ++++ glibc-2.10.1/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/ diff --git a/pkgs/core/glibc/patches/glibc-2.10.1-issetugid-1.patch b/pkgs/core/glibc/patches/glibc-2.10.1-issetugid-1.patch new file mode 100644 index 000000000..2cb97b93b --- /dev/null +++ b/pkgs/core/glibc/patches/glibc-2.10.1-issetugid-1.patch @@ -0,0 +1,243 @@ +Submitted By: Robert Connolly (ashes) +Date: 2007-04-25 +Initial Package Version: 2.5 +Upstream Status: Not Submitted +Origin: Alt-Linux and Me. +Description: This adds the issetugid() library function as a frontend +to the __libc_enable_secure() dynamic linker function. This wasn't really +nescessary, but the patch effectively clones the OpenBSD issetugid() +library function so it can be found and used by packages like Ncurses, +and KDE. Adding this issetugid() wrapper keeps us from needing to patch many +packages to use __libc_enable_secure(). + +You will probably want to install the (modified) manual/issetugid.3 +manual page too. + +diff -Naur glibc-2.5.orig/manual/issetugid.3 glibc-2.5/manual/issetugid.3 +--- glibc-2.5.orig/manual/issetugid.3 1970-01-01 00:00:00.000000000 +0000 ++++ glibc-2.5/manual/issetugid.3 2007-04-25 23:23:21.000000000 +0000 +@@ -0,0 +1,106 @@ ++.\" $OpenBSD: issetugid.2,v 1.18 2003/06/02 20:18:39 millert Exp $ ++.\" ++.\" Copyright (c) 1980, 1991, 1993 ++.\" The Regents of the University of California. All rights reserved. ++.\" ++.\" Redistribution and use in source and binary forms, with or without ++.\" modification, are permitted provided that the following conditions ++.\" are met: ++.\" 1. Redistributions of source code must retain the above copyright ++.\" notice, this list of conditions and the following disclaimer. ++.\" 2. Redistributions in binary form must reproduce the above copyright ++.\" notice, this list of conditions and the following disclaimer in the ++.\" documentation and/or other materials provided with the distribution. ++.\" 3. Neither the name of the University nor the names of its contributors ++.\" may be used to endorse or promote products derived from this software ++.\" without specific prior written permission. ++.\" ++.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ++.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++.\" SUCH DAMAGE. ++.\" ++.Dd August 25, 1996 ++.Dt ISSETUGID 3 ++.Os ++.Sh NAME ++.Nm issetugid ++.Nd is current executable running setuid or setgid ++.Sh SYNOPSIS ++.Fd #include ++.Ft int ++.Fn issetugid void ++.Sh DESCRIPTION ++The ++.Fn issetugid ++function returns 1 if the process was made setuid or setgid as ++the result of the last or other previous ++.Fn execve ++system calls. ++Otherwise it returns 0. ++.Pp ++This function exists so that library routines (inside libtermlib, libc, ++or other libraries) can guarantee safe behavior when used inside ++setuid or setgid programs. This implementation uses the ++__libc_enable_secure() function from Glibc's dynamic linker. ++Some library routines may be passed insufficient information and hence ++not know whether the current program was started setuid or setgid ++because higher level calling code may have made changes to the uid, euid, ++gid, or egid. ++Hence these low-level library routines are unable to determine if they ++are being run with elevated or normal privileges. ++.Pp ++In particular, it is wise to use this call to determine if a ++pathname returned from a ++.Fn getenv ++call may safely be used to ++.Fn open ++the specified file. ++Quite often this is not wise because the status of the effective uid ++is not known. ++.Pp ++The ++.Fn issetugid ++system call's result is unaffected by calls to ++.Fn setuid , ++.Fn setgid , ++or other such calls. ++In case of a ++.Fn fork , ++the child process inherits the same status. ++.Pp ++The status of ++.Fn issetugid ++is only affected by ++.Fn execve . ++If a child process executes a new executable file, a new issetugid ++status will be determined. ++This status is based on the existing process's uid, euid, gid, ++and egid permissions and on the modes of the executable file. ++If the new executable file modes are setuid or setgid, or if ++the existing process is executing the new image with ++uid != euid or gid != egid, the new process will be considered ++issetugid. ++.Sh ERRORS ++The ++.Fn issetugid ++function is always successful, and no return value is reserved to ++indicate an error. ++.Sh SEE ALSO ++.Xr execve 2 , ++.Xr setegid 2 , ++.Xr seteuid 2 , ++.Xr setgid 2 , ++.Xr setuid 2 ++.Sh HISTORY ++The ++.Fn issetugid ++function call first appeared in ++.Ox 2.0 . +diff -Naur glibc-2.5.orig/posix/Makefile glibc-2.5/posix/Makefile +--- glibc-2.5.orig/posix/Makefile 2006-09-07 13:50:05.000000000 +0000 ++++ glibc-2.5/posix/Makefile 2007-04-25 23:23:21.000000000 +0000 +@@ -47,7 +47,7 @@ + getpid getppid \ + getuid geteuid getgid getegid getgroups setuid setgid group_member \ + getpgid setpgid getpgrp bsd-getpgrp setpgrp getsid setsid \ +- getresuid getresgid setresuid setresgid \ ++ getresuid getresgid setresuid setresgid issetugid \ + getlogin getlogin_r setlogin \ + pathconf sysconf fpathconf \ + glob glob64 fnmatch regex \ +diff -Naur glibc-2.5.orig/posix/Versions glibc-2.5/posix/Versions +--- glibc-2.5.orig/posix/Versions 2004-05-03 21:25:44.000000000 +0000 ++++ glibc-2.5/posix/Versions 2007-04-25 23:23:21.000000000 +0000 +@@ -38,6 +38,9 @@ + getopt_long_only; getpgid; getpgrp; getpid; getppid; getsid; getuid; glob; + glob_pattern_p; globfree; group_member; + ++ # i* ++ issetugid; ++ + # n* + nanosleep; + +diff -Naur glibc-2.5.orig/posix/issetugid.c glibc-2.5/posix/issetugid.c +--- glibc-2.5.orig/posix/issetugid.c 1970-01-01 00:00:00.000000000 +0000 ++++ glibc-2.5/posix/issetugid.c 2007-04-25 23:23:21.000000000 +0000 +@@ -0,0 +1,61 @@ ++/* ++ * Copyright (C) - 2007 Robert Connolly ++ * ++ * Permission to reproduce, copy, delete, distribute, transmit, use, modify, ++ * build upon or otherwise exploit this software, in any form, for any ++ * purpose, in any way, and by anyone, including by methods that have not ++ * yet been invented or conceived, is hereby granted. ++ */ ++ ++#include ++ ++extern int __libc_enable_secure; ++ ++int issetugid(void) ++{ ++ if (__libc_enable_secure) ++ { ++ return 1; ++ } ++ ++ if (getuid() != geteuid()) ++ { ++ return 1; ++ } ++ ++ if (getgid() != getegid()) ++ { ++ return 1; ++ } ++ ++ /* Else */ ++ return 0; ++} ++ ++#if defined(TEST) ++ ++# include ++ ++int main(void) ++{ ++ int GETUID=getuid(), GETGID=getgid(); ++ int GETEUID=geteuid(), GETEGID=getegid(); ++ int ISSETUGID=issetugid(); ++ ++ printf("Your real user ID is %d\n", GETUID); ++ printf("Your real group ID is %d\n", GETGID); ++ printf("Your effective user ID is %d\n", GETEUID); ++ printf("Your effective group ID is %d\n", GETEGID); ++ ++ if (ISSETUGID == 1) ++ { ++ printf("issetugid() says this program is SUID\n"); ++ } ++ else ++ { ++ printf("issetugid() says this program is not SUID\n"); ++ } ++ ++ return 0; ++} ++#endif /* TEST */ +diff -Naur glibc-2.5.orig/posix/unistd.h glibc-2.5/posix/unistd.h +--- glibc-2.5.orig/posix/unistd.h 2006-08-24 06:46:27.000000000 +0000 ++++ glibc-2.5/posix/unistd.h 2007-04-25 23:23:21.000000000 +0000 +@@ -648,6 +648,10 @@ + /* Get the effective group ID of the calling process. */ + extern __gid_t getegid (void) __THROW; + ++/* Call __libc_enable_secure() and tell us whether the process is ++ SUID or SGID */ ++extern int issetugid(void); ++ + /* If SIZE is zero, return the number of supplementary groups + the calling process is in. Otherwise, fill in the group IDs + of its supplementary groups in LIST and return the number written. */ +diff -Naur glibc-2.5.orig/scripts/data/localplt-i386-linux-gnu.data glibc-2.5/scripts/data/localplt-i386-linux-gnu.data +--- glibc-2.5.orig/scripts/data/localplt-i386-linux-gnu.data 2006-01-11 21:06:19.000000000 +0000 ++++ glibc-2.5/scripts/data/localplt-i386-linux-gnu.data 2007-04-25 23:23:53.000000000 +0000 +@@ -1,6 +1,10 @@ + libc.so: _Unwind_Find_FDE + libc.so: calloc + libc.so: free ++libc.so: getegid ++libc.so: geteuid ++libc.so: getgid ++libc.so: getuid + libc.so: malloc + libc.so: memalign + libc.so: realloc diff --git a/pkgs/core/glibc/patches/glibc-2.10.1-localedef_trampoline-1.patch b/pkgs/core/glibc/patches/glibc-2.10.1-localedef_trampoline-1.patch new file mode 100644 index 000000000..4d260164b --- /dev/null +++ b/pkgs/core/glibc/patches/glibc-2.10.1-localedef_trampoline-1.patch @@ -0,0 +1,64 @@ +Submitted By: Robert Connolly (ashes) +Date: 2007-05-05 +Initial Package Version: 2.5 +Upstream Status: Rejected - http://sources.redhat.com/bugzilla/show_bug.cgi?id=3333 +Origin: Fedora's glibc-fedora.patch (via glibc-2.5.90-21) +Description: Avoid segmentation faults, or kills, on PaX and Exe-Shield kernels, + and some non-x86 architectures. + +* Sun Jun 01 2003 Jakub Jelinek 2.3.2-46 + - avoid using trampolines in localedef + +This patch is also known as: +local-localedef-fix-trampoline.diff (Debian) +1040_all_2.3.3-localedef-fix-trampoline.patch (Gentoo) + +Also see: +http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=231438 + +diff -Naur glibc-2.5.orig/locale/programs/3level.h glibc-2.5/locale/programs/3level.h +--- glibc-2.5.orig/locale/programs/3level.h 2005-12-07 05:47:27.000000000 +0000 ++++ glibc-2.5/locale/programs/3level.h 2006-10-11 08:05:00.000000000 +0000 +@@ -202,6 +202,42 @@ + } + } + } ++ ++/* 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 diff --git a/pkgs/core/glibc/patches/glibc-2.10.1-mktemp_urandom.patch b/pkgs/core/glibc/patches/glibc-2.10.1-mktemp_urandom.patch new file mode 100644 index 000000000..9819b0e86 --- /dev/null +++ b/pkgs/core/glibc/patches/glibc-2.10.1-mktemp_urandom.patch @@ -0,0 +1,162 @@ +Based on: http://www.uclibc.org/cgi-bin/viewcvs.cgi/trunk/uClibc/libc/misc/\ + internals/tempname.c?rev=8887&r1=5747&r2=8887 + +Use /dev/urandom exclusively with __gen_tempname(), for the mktemp/tmpnam +family, instead of hp-timing, gettimeofday(), or getpid(). + +diff -Naur glibc-2.8-20080929.orig/sysdeps/posix/tempname.c glibc-2.8-20080929/sysdeps/posix/tempname.c +--- glibc-2.8-20080929.orig/sysdeps/posix/tempname.c 2008-03-30 03:30:25.000000000 +0000 ++++ glibc-2.8-20080929/sysdeps/posix/tempname.c 2008-10-15 20:24:16.000000000 +0000 +@@ -51,10 +51,6 @@ + # include + #endif + +-#if HAVE_SYS_TIME_H || _LIBC +-# include +-#endif +- + #if HAVE_STDINT_H || _LIBC + # include + #endif +@@ -93,11 +89,11 @@ + # define struct_stat64 struct stat64 + #else + # define struct_stat64 struct stat +-# define __getpid getpid +-# define __gettimeofday gettimeofday + # define __mkdir mkdir + # define __open open + # define __open64 open ++# define __close close ++# define __read read + # define __lxstat64(version, path, buf) lstat (path, buf) + # define __xstat64(version, path, buf) stat (path, buf) + #endif +@@ -106,25 +102,6 @@ + # define __secure_getenv getenv + #endif + +-#ifdef _LIBC +-# include +-# if HP_TIMING_AVAIL +-# define RANDOM_BITS(Var) \ +- if (__builtin_expect (value == UINT64_C (0), 0)) \ +- { \ +- /* If this is the first time this function is used initialize \ +- the variable we accumulate the value in to some somewhat \ +- random value. If we'd not do this programs at startup time \ +- might have a reduced set of possible names, at least on slow \ +- machines. */ \ +- struct timeval tv; \ +- __gettimeofday (&tv, NULL); \ +- value = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec; \ +- } \ +- HP_TIMING_NOW (Var) +-# endif +-#endif +- + /* Use the widest available unsigned type if uint64_t is not + available. The algorithm below extracts a number less than 62**6 + (approximately 2**35.725) from uint64_t, so ancient hosts where +@@ -209,6 +186,19 @@ + static const char letters[] = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + ++static unsigned int fillrand(unsigned char *buf, unsigned int len) ++{ ++ int fd; ++ unsigned int result = -1; ++ fd = __open("/dev/urandom", O_RDONLY); ++ if (fd >= 0) ++ { ++ result = __read(fd, buf, len); ++ __close(fd); ++ } ++ return result; ++} ++ + /* Generate a temporary file name based on TMPL. TMPL must match the + rules for mk[s]temp (i.e. end in "XXXXXX"). The name constructed + does not exist at the time of the call to __gen_tempname. TMPL is +@@ -220,19 +210,19 @@ + __GT_FILE: create the file using open(O_CREAT|O_EXCL) + and return a read-write fd. The file is mode 0600. + __GT_DIR: create a directory, which will be mode 0700. +- +- We use a clever algorithm to get hard-to-predict names. */ ++*/ + int + __gen_tempname (char *tmpl, int flags, int kind) + { +- int len; ++ int len, i; + char *XXXXXX; + static uint64_t value; +- uint64_t random_time_bits; + unsigned int count; + int fd = -1; + int save_errno = errno; + struct_stat64 st; ++ unsigned char randomness[6]; ++ unsigned int k; + + /* A lower bound on the number of temporary files to attempt to + generate. The maximum total number of temporary file names that +@@ -260,39 +250,19 @@ + /* This is where the Xs start. */ + XXXXXX = &tmpl[len - 6]; + +- /* Get some more or less random data. */ +-#ifdef RANDOM_BITS +- RANDOM_BITS (random_time_bits); +-#else +-# if HAVE_GETTIMEOFDAY || _LIBC +- { +- struct timeval tv; +- __gettimeofday (&tv, NULL); +- random_time_bits = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec; +- } +-# else +- random_time_bits = time (NULL); +-# endif +-#endif +- value += random_time_bits ^ __getpid (); ++ /* Get some random data. */ ++ if (fillrand(randomness, sizeof(randomness)) != sizeof(randomness)) ++ { ++ goto all_done; ++ } ++ for (i = 0 ; i < sizeof(randomness) ; i++) ++ { ++ k = ((randomness[i]) % 62); ++ XXXXXX[i] = letters[k]; ++ } + + for (count = 0; count < attempts; value += 7777, ++count) + { +- uint64_t v = value; +- +- /* Fill in the random bits. */ +- XXXXXX[0] = letters[v % 62]; +- v /= 62; +- XXXXXX[1] = letters[v % 62]; +- v /= 62; +- XXXXXX[2] = letters[v % 62]; +- v /= 62; +- XXXXXX[3] = letters[v % 62]; +- v /= 62; +- XXXXXX[4] = letters[v % 62]; +- v /= 62; +- XXXXXX[5] = letters[v % 62]; +- + switch (kind) + { + case __GT_FILE: +@@ -337,6 +307,7 @@ + } + + /* We got out of the loop because we ran out of combinations to try. */ ++all_done: + __set_errno (EEXIST); + return -1; + } diff --git a/pkgs/core/glibc/patches/glibc-2.10.1-pt_pax-1.patch b/pkgs/core/glibc/patches/glibc-2.10.1-pt_pax-1.patch new file mode 100644 index 000000000..1d6958829 --- /dev/null +++ b/pkgs/core/glibc/patches/glibc-2.10.1-pt_pax-1.patch @@ -0,0 +1,40 @@ +Submitted By: Robert Connolly (ashes) +Date: 2006-10-11 +Initial Package Version: 2.5 +Upstream Status: Not submitted - PaX specific. Will not be accepted upstream. +Origin: http://www.gtlib.cc.gatech.edu/pub/gentoo/gentoo-x86-portage/sys-libs/ \ + glibc/files/2.3.3/glibc-2.3.3_pre20040117-pt_pax.diff +Description: This is needed for Pax. http://pax.grsecurity.net/ +Also see: +http://www.linuxfromscratch.org/hlfs/ + +diff -Naur glibc-2.5.orig/elf/elf.h glibc-2.5/elf/elf.h +--- glibc-2.5.orig/elf/elf.h 2006-07-10 21:54:02.000000000 +0000 ++++ glibc-2.5/elf/elf.h 2006-10-11 21:30:02.000000000 +0000 +@@ -569,6 +569,7 @@ + #define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */ + #define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */ + #define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */ ++#define PT_PAX_FLAGS 0x65041580 /* Indicates PaX flag markings */ + #define PT_LOSUNW 0x6ffffffa + #define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ + #define PT_SUNWSTACK 0x6ffffffb /* Stack segment */ +@@ -582,6 +583,18 @@ + #define PF_X (1 << 0) /* Segment is executable */ + #define PF_W (1 << 1) /* Segment is writable */ + #define PF_R (1 << 2) /* Segment is readable */ ++#define PF_PAGEEXEC (1 << 4) /* Enable PAGEEXEC */ ++#define PF_NOPAGEEXEC (1 << 5) /* Disable PAGEEXEC */ ++#define PF_SEGMEXEC (1 << 6) /* Enable SEGMEXEC */ ++#define PF_NOSEGMEXEC (1 << 7) /* Disable SEGMEXEC */ ++#define PF_MPROTECT (1 << 8) /* Enable MPROTECT */ ++#define PF_NOMPROTECT (1 << 9) /* Disable MPROTECT */ ++#define PF_RANDEXEC (1 << 10) /* Enable RANDEXEC */ ++#define PF_NORANDEXEC (1 << 11) /* Disable RANDEXEC */ ++#define PF_EMUTRAMP (1 << 12) /* Enable EMUTRAMP */ ++#define PF_NOEMUTRAMP (1 << 13) /* Disable EMUTRAMP */ ++#define PF_RANDMMAP (1 << 14) /* Enable RANDMMAP */ ++#define PF_NORANDMMAP (1 << 15) /* Disable RANDMMAP */ + #define PF_MASKOS 0x0ff00000 /* OS-specific */ + #define PF_MASKPROC 0xf0000000 /* Processor-specific */ + diff --git a/pkgs/core/glibc/patches/glibc-2.10.1-res_randomid.patch b/pkgs/core/glibc/patches/glibc-2.10.1-res_randomid.patch new file mode 100644 index 000000000..db843f091 --- /dev/null +++ b/pkgs/core/glibc/patches/glibc-2.10.1-res_randomid.patch @@ -0,0 +1,339 @@ +From Alt Linux glibc-2.5-owl-alt-res_randomid.patch + +See: http://www.openbsd.org/advisories/res_random.txt + +Bind needs to be modified to use this res_randomid(), and not its own (which +is almost as bad as Glibc's vanilla version). + +Note: undefine CONSERVE_KERNEL_RANDOMNESS in resolv/shuffle.c when using +/dev/erandom. + +diff -Naur glibc-2.8-20080929.orig/include/resolv.h glibc-2.8-20080929/include/resolv.h +--- glibc-2.8-20080929.orig/include/resolv.h 2007-02-09 23:46:19.000000000 +0000 ++++ glibc-2.8-20080929/include/resolv.h 2008-10-16 01:16:24.000000000 +0000 +@@ -31,6 +31,7 @@ + # endif + + /* Now define the internal interfaces. */ ++extern unsigned int _shuffle_next (void); + extern int __res_vinit (res_state, int); + extern int __res_maybe_init (res_state, int); + extern void _sethtent (int); +diff -Naur glibc-2.8-20080929.orig/resolv/Makefile glibc-2.8-20080929/resolv/Makefile +--- glibc-2.8-20080929.orig/resolv/Makefile 2007-04-30 22:30:05.000000000 +0000 ++++ glibc-2.8-20080929/resolv/Makefile 2008-10-16 01:16:24.000000000 +0000 +@@ -30,7 +30,7 @@ + Banner res_hconf.h res_debug.h README gai_misc.h ga_test.c + + routines := herror inet_addr inet_ntop inet_pton nsap_addr res_init \ +- res_hconf res_libc res-state ++ res_hconf res_libc res-state shuffle + + tests = tst-aton tst-leaks tst-inet_ntop + xtests = tst-leaks2 +@@ -49,7 +49,7 @@ + res_data res_mkquery res_query res_send \ + inet_net_ntop inet_net_pton inet_neta base64 \ + ns_parse ns_name ns_netint ns_ttl ns_print \ +- ns_samedomain ns_date ++ ns_samedomain ns_date shuffle + + libanl-routines := gai_cancel gai_error gai_misc gai_notify gai_suspend \ + getaddrinfo_a +diff -Naur glibc-2.8-20080929.orig/resolv/res_init.c glibc-2.8-20080929/resolv/res_init.c +--- glibc-2.8-20080929.orig/resolv/res_init.c 2008-04-07 17:20:25.000000000 +0000 ++++ glibc-2.8-20080929/resolv/res_init.c 2008-10-16 01:16:24.000000000 +0000 +@@ -568,7 +568,9 @@ + + u_int + res_randomid(void) { +- return 0xffff & __getpid(); ++/* We should probably randomize the port number as well, ++ * but this may be better done in the kernel */ ++ return _shuffle_next(); + } + #ifdef _LIBC + libc_hidden_def (__res_randomid) +diff -Naur glibc-2.8-20080929.orig/resolv/res_mkquery.c glibc-2.8-20080929/resolv/res_mkquery.c +--- glibc-2.8-20080929.orig/resolv/res_mkquery.c 2007-02-09 23:42:17.000000000 +0000 ++++ glibc-2.8-20080929/resolv/res_mkquery.c 2008-10-16 01:16:24.000000000 +0000 +@@ -120,6 +120,7 @@ + return (-1); + memset(buf, 0, HFIXEDSZ); + hp = (HEADER *) buf; ++#if 0 + /* We randomize the IDs every time. The old code just + incremented by one after the initial randomization which + still predictable if the application does multiple +@@ -137,6 +138,9 @@ + } + while ((randombits & 0xffff) == 0); + statp->id = (statp->id + randombits) & 0xffff; ++#else ++ statp->id = _shuffle_next(); ++#endif + hp->id = statp->id; + hp->opcode = op; + hp->rd = (statp->options & RES_RECURSE) != 0; +diff -Naur glibc-2.8-20080929.orig/resolv/shuffle.c glibc-2.8-20080929/resolv/shuffle.c +--- glibc-2.8-20080929.orig/resolv/shuffle.c 1970-01-01 00:00:00.000000000 +0000 ++++ glibc-2.8-20080929/resolv/shuffle.c 2008-10-16 01:16:24.000000000 +0000 +@@ -0,0 +1,258 @@ ++/* ++ * Written by Solar Designer and placed in the public domain. ++ */ ++ ++#include ++#include ++#include ++ ++#ifdef __linux__ ++#define DEVICE "/dev/urandom" ++#else ++#undef DEVICE ++#endif ++ ++#if defined(DEVICE) && defined(_LIBC) ++#define CONSERVE_KERNEL_RANDOMNESS ++#else ++#undef CONSERVE_KERNEL_RANDOMNESS ++#endif ++ ++#ifdef DEVICE ++#include ++#endif ++ ++#include ++#include ++#include ++#include ++ ++#ifdef TEST ++#include ++#endif ++ ++#define DIV 0x8000 ++ ++static unsigned char pool[0x100]; ++ ++static struct { ++ unsigned int base, xor; ++ unsigned char s[0x80]; ++} seed_c; ++static unsigned char seed_f[0x100]; ++ ++static struct { ++ unsigned int msb; ++ unsigned int a, b; ++ unsigned int n; ++} state; ++ ++static void pool_update(unsigned int seed) ++{ ++ int i, x; ++ ++ srand(seed ^ rand()); ++ for (i = 0; i < sizeof(pool); i++) { ++ x = rand(); ++ pool[i] += (x >> 16) ^ x; ++ } ++} ++ ++#ifdef DEVICE ++static int read_loop(int fd, char *buffer, int count) ++{ ++ int offset, block; ++ ++ offset = 0; ++ while (count > 0) { ++ block = read(fd, &buffer[offset], count); ++ ++ if (block < 0) { ++ if (errno == EINTR) continue; ++ return block; ++ } ++ if (!block) return offset; ++ ++ offset += block; ++ count -= block; ++ } ++ ++ return offset; ++} ++ ++static int read_random(char *buffer, int count) ++{ ++ int fd; ++#ifdef CONSERVE_KERNEL_RANDOMNESS ++ unsigned int seed[2]; ++ ++ if (count > sizeof(pool)) ++ return -1; ++#endif ++ ++ if ((fd = open(DEVICE, O_RDONLY)) < 0) ++ return -1; ++ ++#ifdef CONSERVE_KERNEL_RANDOMNESS ++ if (read_loop(fd, (char *)seed, sizeof(seed)) != sizeof(seed)) { ++ close(fd); ++ return -1; ++ } ++ close(fd); ++ ++ memset(pool, 'X', sizeof(pool)); ++ pool_update(seed[0]); ++ pool_update(seed[1]); ++ ++ memcpy(buffer, pool, count); ++#else ++ count = read_loop(fd, buffer, count); ++ close(fd); ++#endif ++ ++ return count; ++} ++#else ++#define read_random(buffer, count) (-1) ++#endif ++ ++static void shuffle_init() ++{ ++ struct timeval tv; ++ ++ if (read_random((char *)seed_f, sizeof(seed_f)) != sizeof(seed_f)) { ++ memset(pool, 'X', sizeof(pool)); ++ pool_update(getpid()); ++ pool_update(getppid()); ++ if (!gettimeofday(&tv, NULL)) { ++ pool_update(tv.tv_sec); ++ pool_update(tv.tv_usec); ++ } ++ ++ memcpy(seed_f, pool, sizeof(seed_f)); ++ } ++ ++ state.msb = 0; ++ state.n = DIV; /* force a reseed() */ ++} ++ ++static void reseed() ++{ ++ struct tms buf; ++ ++ if (read_random((char *)&seed_c, sizeof(seed_c)) != sizeof(seed_c)) { ++ pool_update(times(&buf)); ++ pool_update(buf.tms_utime); ++ pool_update(buf.tms_stime); ++ ++ memcpy(&seed_c, pool, sizeof(seed_c)); ++ } ++ ++ seed_c.base &= 0x1fff; ++ seed_c.base <<= 3; ++ seed_c.base += DIV + 3; ++ seed_c.xor &= (DIV - 1); ++ state.msb ^= 0x8000; ++ state.a = 1; ++ state.b = 1; ++ state.n = 0; ++} ++ ++/* ++ * Now, time for a puzzle. Think of division by DIV in seed_c.base. ++ * This is not as slow as it might appear: the inner loop needs only ++ * a few iterations per call, on average. ++ */ ++static unsigned int shuffle_1_next() ++{ ++ if (state.n >= DIV - 1) ++ reseed(); ++ ++ if (state.n && state.b <= state.a) { ++ do { ++ state.b = ++state.a; ++ do { ++ state.b *= seed_c.base; ++ state.b %= DIV; ++ } while (state.b > state.a); ++ } while (state.a != state.b); ++ } ++ ++ state.b *= seed_c.base; ++ state.b %= DIV; ++ state.n++; ++ ++ return state.b ^ seed_c.xor; ++} ++ ++/* ++ * The idea behind shuffle_2 is David Wagner's (any bugs are mine, ++ * of course). ++ */ ++static unsigned int shuffle_2(unsigned int x) ++{ ++ unsigned int i, sum; ++ ++ sum = 0; ++ for (i = 0; i < 8; i++) { ++ sum += 0x79b9; ++ x ^= ((unsigned int)seed_c.s[(x ^ sum) & 0x7f]) << 7; ++ x = ((x & 0xff) << 7) | (x >> 8); ++ } ++ ++ return x; ++} ++ ++/* ++ * A full 16-bit permutation. This one can't be re-seeded, but still ++ * makes some attacks quite a bit harder. ++ */ ++static unsigned int shuffle_3(unsigned int x) ++{ ++ unsigned int i, sum; ++ ++ sum = 0; ++ for (i = 0; i < 8; i++) { ++ sum += 0x79b9; ++ x ^= ((unsigned int)seed_f[(x ^ sum) & 0xff]) << 8; ++ x = ((x & 0xff) << 8) | (x >> 8); ++ } ++ ++ return x; ++} ++ ++unsigned int _shuffle_next() ++{ ++ static int initialized = 0; ++ unsigned int pid, x; ++ ++/* This isn't MT-safe, but the resolver itself isn't safe, anyway */ ++ if (!initialized) { ++ shuffle_init(); ++ initialized = 1; ++ } ++ ++/* Make sure the sequence we generate changes after fork() */ ++ pid = getpid(); ++ ++ x = shuffle_1_next(); ++ x ^= pid & 0x7fff; ++ x = shuffle_2(x); ++ x |= state.msb; ++ x ^= (pid >> 15) & 0xffff; ++ x = shuffle_3(x); ++ ++ return x; ++} ++ ++#ifdef TEST ++int main() ++{ ++ int i; ++ ++ for (i = 0; i < 0xfffe; i++) ++ printf("%u\n", _shuffle_next()); ++ ++ return 0; ++} ++#endif diff --git a/pkgs/core/glibc/patches/glibc-2.10.1-resolv_response_length.patch b/pkgs/core/glibc/patches/glibc-2.10.1-resolv_response_length.patch new file mode 100644 index 000000000..1de4c1be0 --- /dev/null +++ b/pkgs/core/glibc/patches/glibc-2.10.1-resolv_response_length.patch @@ -0,0 +1,26 @@ +From: Owl Linux glibc-2.3.2-suse-resolv-response-length.diff + +Warning: This patch can screw up applications that expect the vanilla +behavior. See: http://webui.sourcelabs.com/samba/issues/4014 + +diff -Naur glibc-2.8-20080929.orig/resolv/res_send.c glibc-2.8-20080929/resolv/res_send.c +--- glibc-2.8-20080929.orig/resolv/res_send.c 2007-08-22 04:02:38.000000000 +0000 ++++ glibc-2.8-20080929/resolv/res_send.c 2008-10-17 03:17:19.000000000 +0000 +@@ -384,6 +384,17 @@ + needclose++; + break; + } ++ /* ++ * Dirty fix - avoid read buffer overruns in ++ * applications that naively assume the length ++ * returned by res_* is always less than or ++ * equal the answer buffer size. ++ * ++ * Simply truncating the answer here surely ++ * beats fixing all calls of res_* in all ++ * applications. ++ */ ++ resplen = anssiz; + } + if (needclose) + __res_iclose(statp, false); diff --git a/pkgs/core/glibc/patches/glibc-2.10.1-sanitize_env.patch b/pkgs/core/glibc/patches/glibc-2.10.1-sanitize_env.patch new file mode 100644 index 000000000..5d0e9422d --- /dev/null +++ b/pkgs/core/glibc/patches/glibc-2.10.1-sanitize_env.patch @@ -0,0 +1,1062 @@ +From: http://sisyphus.ru/srpm/Sisyphus/glibc/patches/10 + +I added MUDFLAP_OPTIONS to sysdeps/generic/unsecvars.h. + +diff -Naur glibc-2.8-20080929.orig/argp/argp-help.c glibc-2.8-20080929/argp/argp-help.c +--- glibc-2.8-20080929.orig/argp/argp-help.c 2007-03-15 20:08:18.000000000 +0000 ++++ glibc-2.8-20080929/argp/argp-help.c 2008-10-15 00:30:49.000000000 +0000 +@@ -165,7 +165,7 @@ + static void + fill_in_uparams (const struct argp_state *state) + { +- const char *var = getenv ("ARGP_HELP_FMT"); ++ const char *var = __secure_getenv ("ARGP_HELP_FMT"); + + #define SKIPWS(p) do { while (isspace (*p)) p++; } while (0); + +diff -Naur glibc-2.8-20080929.orig/catgets/catgets.c glibc-2.8-20080929/catgets/catgets.c +--- glibc-2.8-20080929.orig/catgets/catgets.c 2002-05-15 03:46:42.000000000 +0000 ++++ glibc-2.8-20080929/catgets/catgets.c 2008-10-15 00:30:49.000000000 +0000 +@@ -50,7 +50,7 @@ + || (__libc_enable_secure && strchr (env_var, '/') != NULL)) + env_var = "C"; + +- nlspath = getenv ("NLSPATH"); ++ nlspath = __secure_getenv ("NLSPATH"); + if (nlspath != NULL && *nlspath != '\0') + { + /* Append the system dependent directory. */ +diff -Naur glibc-2.8-20080929.orig/debug/pcprofile.c glibc-2.8-20080929/debug/pcprofile.c +--- glibc-2.8-20080929.orig/debug/pcprofile.c 2001-07-06 04:54:45.000000000 +0000 ++++ glibc-2.8-20080929/debug/pcprofile.c 2008-10-15 00:30:49.000000000 +0000 +@@ -38,7 +38,7 @@ + { + /* See whether the environment variable `PCPROFILE_OUTPUT' is defined. + If yes, it should name a FIFO. We open it and mark ourself as active. */ +- const char *outfile = getenv ("PCPROFILE_OUTPUT"); ++ const char *outfile = __secure_getenv ("PCPROFILE_OUTPUT"); + + if (outfile != NULL && *outfile != '\0') + { +diff -Naur glibc-2.8-20080929.orig/debug/segfault.c glibc-2.8-20080929/debug/segfault.c +--- glibc-2.8-20080929.orig/debug/segfault.c 2007-08-22 06:52:12.000000000 +0000 ++++ glibc-2.8-20080929/debug/segfault.c 2008-10-15 00:30:49.000000000 +0000 +@@ -149,7 +149,7 @@ + install_handler (void) + { + struct sigaction sa; +- const char *sigs = getenv ("SEGFAULT_SIGNALS"); ++ const char *sigs = __secure_getenv ("SEGFAULT_SIGNALS"); + const char *name; + + sa.sa_handler = (void *) catch_segfault; +@@ -157,7 +157,7 @@ + sa.sa_flags = SA_RESTART; + + /* Maybe we are expected to use an alternative stack. */ +- if (getenv ("SEGFAULT_USE_ALTSTACK") != 0) ++ if (__secure_getenv ("SEGFAULT_USE_ALTSTACK") != 0) + { + void *stack_mem = malloc (2 * SIGSTKSZ); + struct sigaltstack ss; +@@ -203,7 +203,7 @@ + } + + /* Preserve the output file name if there is any given. */ +- name = getenv ("SEGFAULT_OUTPUT_NAME"); ++ name = __secure_getenv ("SEGFAULT_OUTPUT_NAME"); + if (name != NULL && name[0] != '\0') + { + int ret = access (name, R_OK | W_OK); +diff -Naur glibc-2.8-20080929.orig/elf/Versions glibc-2.8-20080929/elf/Versions +--- glibc-2.8-20080929.orig/elf/Versions 2008-03-08 05:42:26.000000000 +0000 ++++ glibc-2.8-20080929/elf/Versions 2008-10-15 00:30:49.000000000 +0000 +@@ -60,6 +60,8 @@ + _dl_make_stack_executable; + # Only here for gdb while a better method is developed. + _dl_debug_state; ++ # For sanitizing environment. ++ __libc_security_mask; + # Pointer protection. + __pointer_chk_guard; + } +diff -Naur glibc-2.8-20080929.orig/elf/dl-support.c glibc-2.8-20080929/elf/dl-support.c +--- glibc-2.8-20080929.orig/elf/dl-support.c 2007-06-20 03:18:16.000000000 +0000 ++++ glibc-2.8-20080929/elf/dl-support.c 2008-10-15 00:30:49.000000000 +0000 +@@ -163,6 +163,7 @@ + internal_function + _dl_aux_init (ElfW(auxv_t) *av) + { ++ int security_mask = 0; + int seen = 0; + uid_t uid = 0; + gid_t gid = 0; +@@ -196,25 +197,27 @@ + break; + #endif + case AT_UID: ++ if (seen & 1) break; + uid ^= av->a_un.a_val; + seen |= 1; + break; + case AT_EUID: ++ if (seen & 2) break; + uid ^= av->a_un.a_val; + seen |= 2; + break; + case AT_GID: ++ if (seen & 4) break; + gid ^= av->a_un.a_val; + seen |= 4; + break; + case AT_EGID: ++ if (seen & 8) break; + gid ^= av->a_un.a_val; + seen |= 8; + break; + case AT_SECURE: +- seen = -1; +- __libc_enable_secure = av->a_un.a_val; +- __libc_enable_secure_decided = 1; ++ security_mask |= av->a_un.a_val != 0; + break; + # ifdef DL_PLATFORM_AUXV + DL_PLATFORM_AUXV +@@ -222,7 +225,9 @@ + } + if (seen == 0xf) + { +- __libc_enable_secure = uid != 0 || gid != 0; ++ security_mask |= ((uid != 0) << 1) | ((gid != 0) << 2); ++ __libc_security_mask = security_mask; ++ __libc_enable_secure = __libc_security_mask != 0; + __libc_enable_secure_decided = 1; + } + } +@@ -239,19 +244,19 @@ + if (!_dl_pagesize) + _dl_pagesize = __getpagesize (); + +- _dl_verbose = *(getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1; ++ _dl_verbose = *(__secure_getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1; + + /* Initialize the data structures for the search paths for shared + objects. */ +- _dl_init_paths (getenv ("LD_LIBRARY_PATH")); ++ _dl_init_paths (__secure_getenv ("LD_LIBRARY_PATH")); + +- _dl_lazy = *(getenv ("LD_BIND_NOW") ?: "") == '\0'; ++ _dl_lazy = *(__secure_getenv ("LD_BIND_NOW") ?: "") == '\0'; + +- _dl_bind_not = *(getenv ("LD_BIND_NOT") ?: "") != '\0'; ++ _dl_bind_not = *(__secure_getenv ("LD_BIND_NOT") ?: "") != '\0'; + +- _dl_dynamic_weak = *(getenv ("LD_DYNAMIC_WEAK") ?: "") == '\0'; ++ _dl_dynamic_weak = *(__secure_getenv ("LD_DYNAMIC_WEAK") ?: "") == '\0'; + +- _dl_profile_output = getenv ("LD_PROFILE_OUTPUT"); ++ _dl_profile_output = __secure_getenv ("LD_PROFILE_OUTPUT"); + if (_dl_profile_output == NULL || _dl_profile_output[0] == '\0') + _dl_profile_output + = &"/var/tmp\0/var/profile"[__libc_enable_secure ? 9 : 0]; +@@ -264,6 +269,8 @@ + EXTRA_UNSECURE_ENVVARS + #endif + ; ++ static const char restricted_envvars[] = ++ RESTRICTED_ENVVARS; + const char *cp = unsecure_envvars; + + while (cp < unsecure_envvars + sizeof (unsecure_envvars)) +@@ -272,8 +279,31 @@ + cp = (const char *) __rawmemchr (cp, '\0') + 1; + } + +- if (__access ("/etc/suid-debug", F_OK) != 0) +- __unsetenv ("MALLOC_CHECK_"); ++ if (__libc_security_mask & 2) ++ { ++ static const char unsecure_uid_envvars[] = ++ UNSECURE_UID_ENVVARS; ++ ++ cp = unsecure_uid_envvars; ++ while (cp < unsecure_uid_envvars + sizeof (unsecure_uid_envvars)) ++ { ++ __unsetenv (cp); ++ cp = (const char *) __rawmemchr (cp, '\0') + 1; ++ } ++ } ++ ++ /* This loop is buggy: it will only check the first occurrence of each ++ variable (but will correctly remove all in case of a match). This ++ may be a problem if the list is later re-ordered or accessed by an ++ application with something other than the glibc getenv(). */ ++ cp = restricted_envvars; ++ while (cp < restricted_envvars + sizeof (restricted_envvars)) ++ { ++ const char *value = getenv (cp); ++ if (value && (value[0] == '.' || strchr(value, '/'))) ++ __unsetenv (cp); ++ cp = (const char *) __rawmemchr (cp, '\0') + 1; ++ } + } + + #ifdef DL_PLATFORM_INIT +diff -Naur glibc-2.8-20080929.orig/elf/dl-sysdep.c glibc-2.8-20080929/elf/dl-sysdep.c +--- glibc-2.8-20080929.orig/elf/dl-sysdep.c 2008-03-08 07:28:36.000000000 +0000 ++++ glibc-2.8-20080929/elf/dl-sysdep.c 2008-10-15 00:30:49.000000000 +0000 +@@ -54,8 +54,10 @@ + #ifdef NEED_DL_BASE_ADDR + ElfW(Addr) _dl_base_addr; + #endif +-int __libc_enable_secure attribute_relro = 0; ++int __libc_enable_secure attribute_relro = 1; + INTVARDEF(__libc_enable_secure) ++int __libc_security_mask attribute_relro = 0x7fffffff; ++INTVARDEF(__libc_security_mask) + int __libc_multiple_libcs = 0; /* Defining this here avoids the inclusion + of init-first. */ + /* This variable contains the lowest stack address ever used. */ +@@ -80,6 +82,10 @@ + # define DL_STACK_END(cookie) ((void *) (cookie)) + #endif + ++#ifdef HAVE_AUX_XID ++#undef HAVE_AUX_XID ++#endif ++ + ElfW(Addr) + _dl_sysdep_start (void **start_argptr, + void (*dl_main) (const ElfW(Phdr) *phdr, ElfW(Word) phnum, +@@ -89,19 +95,19 @@ + ElfW(Word) phnum = 0; + ElfW(Addr) user_entry; + ElfW(auxv_t) *av; +-#ifdef HAVE_AUX_SECURE ++ int security_mask = 0; ++#if 0 + # define set_seen(tag) (tag) /* Evaluate for the side effects. */ +-# define set_seen_secure() ((void) 0) + #else + uid_t uid = 0; + gid_t gid = 0; + unsigned int seen = 0; +-# define set_seen_secure() (seen = -1) + # ifdef HAVE_AUX_XID + # define set_seen(tag) (tag) /* Evaluate for the side effects. */ + # else + # define M(type) (1 << (type)) + # define set_seen(tag) seen |= M ((tag)->a_type) ++# define is_seen(tag) seen & M ((tag)->a_type) + # endif + #endif + #ifdef NEED_DL_SYSINFO +@@ -135,21 +141,18 @@ + _dl_base_addr = av->a_un.a_val; + break; + #endif +-#ifndef HAVE_AUX_SECURE + case AT_UID: + case AT_EUID: ++ if (is_seen (av)) break; + uid ^= av->a_un.a_val; + break; + case AT_GID: + case AT_EGID: ++ if (is_seen (av)) break; + gid ^= av->a_un.a_val; + break; +-#endif + case AT_SECURE: +-#ifndef HAVE_AUX_SECURE +- seen = -1; +-#endif +- INTUSE(__libc_enable_secure) = av->a_un.a_val; ++ security_mask |= av->a_un.a_val != 0; + break; + case AT_PLATFORM: + GLRO(dl_platform) = (void *) av->a_un.a_val; +@@ -178,8 +181,6 @@ + #endif + } + +-#ifndef HAVE_AUX_SECURE +- if (seen != -1) + { + /* Fill in the values we have not gotten from the kernel through the + auxiliary vector. */ +@@ -191,12 +192,12 @@ + SEE (GID, gid, gid); + SEE (EGID, gid, egid); + # endif +- +- /* If one of the two pairs of IDs does not match this is a setuid +- or setgid run. */ +- INTUSE(__libc_enable_secure) = uid | gid; + } +-#endif ++ /* If one of the two pairs of IDs does not match ++ this is a setuid or setgid run. */ ++ security_mask |= ((uid != 0) << 1) | ((gid != 0) << 2); ++ INTUSE(__libc_security_mask) = security_mask; ++ INTUSE(__libc_enable_secure) = security_mask != 0; + + #ifndef HAVE_AUX_PAGESIZE + if (GLRO(dl_pagesize) == 0) +diff -Naur glibc-2.8-20080929.orig/elf/enbl-secure.c glibc-2.8-20080929/elf/enbl-secure.c +--- glibc-2.8-20080929.orig/elf/enbl-secure.c 2005-12-14 08:46:07.000000000 +0000 ++++ glibc-2.8-20080929/elf/enbl-secure.c 2008-10-15 00:30:49.000000000 +0000 +@@ -27,11 +27,17 @@ + int __libc_enable_secure_decided; + /* Safest assumption, if somehow the initializer isn't run. */ + int __libc_enable_secure = 1; ++int __libc_security_mask = 0x7fffffff; + + void + __libc_init_secure (void) + { + if (__libc_enable_secure_decided == 0) +- __libc_enable_secure = (__geteuid () != __getuid () +- || __getegid () != __getgid ()); ++ { ++ __libc_security_mask = ++ ((__geteuid () != __getuid ()) << 1) | ++ ((__getegid () != __getgid ()) << 2); ++ __libc_enable_secure = __libc_security_mask != 0; ++ __libc_security_mask |= __libc_enable_secure; ++ } + } +diff -Naur glibc-2.8-20080929.orig/elf/rtld.c glibc-2.8-20080929/elf/rtld.c +--- glibc-2.8-20080929.orig/elf/rtld.c 2008-03-08 07:29:40.000000000 +0000 ++++ glibc-2.8-20080929/elf/rtld.c 2008-10-15 00:30:49.000000000 +0000 +@@ -2500,6 +2500,7 @@ + GLRO(dl_profile_output) + = &"/var/tmp\0/var/profile"[INTUSE(__libc_enable_secure) ? 9 : 0]; + ++ if (__builtin_expect (!INTUSE(__libc_enable_secure), 1)) + while ((envline = _dl_next_ld_env_entry (&runp)) != NULL) + { + size_t len = 0; +@@ -2566,8 +2567,7 @@ + case 9: + /* Test whether we want to see the content of the auxiliary + array passed up from the kernel. */ +- if (!INTUSE(__libc_enable_secure) +- && memcmp (envline, "SHOW_AUXV", 9) == 0) ++ if (memcmp (envline, "SHOW_AUXV", 9) == 0) + _dl_show_auxv (); + break; + +@@ -2580,8 +2580,7 @@ + + case 11: + /* Path where the binary is found. */ +- if (!INTUSE(__libc_enable_secure) +- && memcmp (envline, "ORIGIN_PATH", 11) == 0) ++ if (memcmp (envline, "ORIGIN_PATH", 11) == 0) + GLRO(dl_origin_path) = &envline[12]; + break; + +@@ -2600,8 +2599,7 @@ + break; + } + +- if (!INTUSE(__libc_enable_secure) +- && memcmp (envline, "DYNAMIC_WEAK", 12) == 0) ++ if (memcmp (envline, "DYNAMIC_WEAK", 12) == 0) + GLRO(dl_dynamic_weak) = 1; + break; + +@@ -2611,8 +2609,7 @@ + #ifdef EXTRA_LD_ENVVARS_13 + EXTRA_LD_ENVVARS_13 + #endif +- if (!INTUSE(__libc_enable_secure) +- && memcmp (envline, "USE_LOAD_BIAS", 13) == 0) ++ if (memcmp (envline, "USE_LOAD_BIAS", 13) == 0) + { + GLRO(dl_use_load_bias) = envline[14] == '1' ? -1 : 0; + break; +@@ -2624,8 +2621,7 @@ + + case 14: + /* Where to place the profiling data file. */ +- if (!INTUSE(__libc_enable_secure) +- && memcmp (envline, "PROFILE_OUTPUT", 14) == 0 ++ if (memcmp (envline, "PROFILE_OUTPUT", 14) == 0 + && envline[15] != '\0') + GLRO(dl_profile_output) = &envline[15]; + break; +@@ -2669,16 +2665,39 @@ + EXTRA_UNSECURE_ENVVARS + #endif + UNSECURE_ENVVARS; ++ static const char restricted_envvars[] = ++ RESTRICTED_ENVVARS; + const char *nextp; + +- nextp = unsecure_envvars; +- do ++ for (nextp = unsecure_envvars; *nextp != '\0'; ++ nextp = (char *) rawmemchr (nextp, '\0') + 1) + { + unsetenv (nextp); +- /* We could use rawmemchr but this need not be fast. */ +- nextp = (char *) (strchr) (nextp, '\0') + 1; + } +- while (*nextp != '\0'); ++ ++ if (__builtin_expect (INTUSE(__libc_security_mask) & 2, 0)) ++ { ++ static const char unsecure_uid_envvars[] = ++ UNSECURE_UID_ENVVARS; ++ ++ for (nextp = unsecure_uid_envvars; *nextp != '\0'; ++ nextp = (char *) rawmemchr (nextp, '\0') + 1) ++ { ++ unsetenv (nextp); ++ } ++ } ++ ++ /* This loop is buggy: it will only check the first occurrence of each ++ variable (but will correctly remove all in case of a match). This ++ may be a problem if the list is later re-ordered or accessed by an ++ application with something other than the glibc getenv(). */ ++ for (nextp = restricted_envvars; *nextp != '\0'; ++ nextp = (char *) rawmemchr (nextp, '\0') + 1) ++ { ++ const char *value = getenv (nextp); ++ if (value && (value[0] == '.' || strchr(value, '/'))) ++ unsetenv (nextp); ++ } + + if (__access ("/etc/suid-debug", F_OK) != 0) + { +diff -Naur glibc-2.8-20080929.orig/gmon/gmon.c glibc-2.8-20080929/gmon/gmon.c +--- glibc-2.8-20080929.orig/gmon/gmon.c 2008-03-19 06:43:31.000000000 +0000 ++++ glibc-2.8-20080929/gmon/gmon.c 2008-10-15 00:30:49.000000000 +0000 +@@ -326,8 +326,8 @@ + # define O_NOFOLLOW 0 + #endif + +- env = getenv ("GMON_OUT_PREFIX"); +- if (env != NULL && !__libc_enable_secure) ++ env = __secure_getenv ("GMON_OUT_PREFIX"); ++ if (env != NULL) + { + size_t len = strlen (env); + char buf[len + 20]; +diff -Naur glibc-2.8-20080929.orig/iconv/gconv_cache.c glibc-2.8-20080929/iconv/gconv_cache.c +--- glibc-2.8-20080929.orig/iconv/gconv_cache.c 2007-07-28 19:00:25.000000000 +0000 ++++ glibc-2.8-20080929/iconv/gconv_cache.c 2008-10-15 00:30:49.000000000 +0000 +@@ -55,7 +55,7 @@ + + /* We cannot use the cache if the GCONV_PATH environment variable is + set. */ +- __gconv_path_envvar = getenv ("GCONV_PATH"); ++ __gconv_path_envvar = __secure_getenv ("GCONV_PATH"); + if (__gconv_path_envvar != NULL) + return -1; + +diff -Naur glibc-2.8-20080929.orig/include/unistd.h glibc-2.8-20080929/include/unistd.h +--- glibc-2.8-20080929.orig/include/unistd.h 2006-07-31 05:57:52.000000000 +0000 ++++ glibc-2.8-20080929/include/unistd.h 2008-10-15 00:30:49.000000000 +0000 +@@ -142,10 +142,12 @@ + and some functions contained in the C library ignore various + environment variables that normally affect them. */ + extern int __libc_enable_secure attribute_relro; ++extern int __libc_security_mask attribute_relro; + extern int __libc_enable_secure_decided; + #ifdef IS_IN_rtld + /* XXX The #ifdef should go. */ + extern int __libc_enable_secure_internal attribute_relro attribute_hidden; ++extern int __libc_security_mask_internal attribute_relro attribute_hidden; + #endif + + +diff -Naur glibc-2.8-20080929.orig/intl/dcigettext.c glibc-2.8-20080929/intl/dcigettext.c +--- glibc-2.8-20080929.orig/intl/dcigettext.c 2008-03-31 00:37:17.000000000 +0000 ++++ glibc-2.8-20080929/intl/dcigettext.c 2008-10-15 00:30:49.000000000 +0000 +@@ -1391,7 +1391,7 @@ + + if (!output_charset_cached) + { +- const char *value = getenv ("OUTPUT_CHARSET"); ++ const char *value = __secure_getenv ("OUTPUT_CHARSET"); + + if (value != NULL && value[0] != '\0') + { +diff -Naur glibc-2.8-20080929.orig/io/getdirname.c glibc-2.8-20080929/io/getdirname.c +--- glibc-2.8-20080929.orig/io/getdirname.c 2001-07-06 04:54:53.000000000 +0000 ++++ glibc-2.8-20080929/io/getdirname.c 2008-10-15 00:30:49.000000000 +0000 +@@ -31,7 +31,7 @@ + char *pwd; + struct stat64 dotstat, pwdstat; + +- pwd = getenv ("PWD"); ++ pwd = __secure_getenv ("PWD"); + if (pwd != NULL + && stat64 (".", &dotstat) == 0 + && stat64 (pwd, &pwdstat) == 0 +diff -Naur glibc-2.8-20080929.orig/libidn/toutf8.c glibc-2.8-20080929/libidn/toutf8.c +--- glibc-2.8-20080929.orig/libidn/toutf8.c 2005-02-22 01:25:30.000000000 +0000 ++++ glibc-2.8-20080929/libidn/toutf8.c 2008-10-15 00:30:49.000000000 +0000 +@@ -74,7 +74,7 @@ + const char * + stringprep_locale_charset (void) + { +- const char *charset = getenv ("CHARSET"); /* flawfinder: ignore */ ++ const char *charset = __secure_getenv ("CHARSET"); + + if (charset && *charset) + return charset; +diff -Naur glibc-2.8-20080929.orig/locale/newlocale.c glibc-2.8-20080929/locale/newlocale.c +--- glibc-2.8-20080929.orig/locale/newlocale.c 2008-03-31 00:37:03.000000000 +0000 ++++ glibc-2.8-20080929/locale/newlocale.c 2008-10-15 00:30:49.000000000 +0000 +@@ -104,7 +104,7 @@ + locale_path = NULL; + locale_path_len = 0; + +- locpath_var = getenv ("LOCPATH"); ++ locpath_var = __secure_getenv ("LOCPATH"); + if (locpath_var != NULL && locpath_var[0] != '\0') + { + if (__argz_create_sep (locpath_var, ':', +diff -Naur glibc-2.8-20080929.orig/locale/setlocale.c glibc-2.8-20080929/locale/setlocale.c +--- glibc-2.8-20080929.orig/locale/setlocale.c 2008-03-31 00:37:03.000000000 +0000 ++++ glibc-2.8-20080929/locale/setlocale.c 2008-10-15 00:30:49.000000000 +0000 +@@ -246,7 +246,7 @@ + locale_path = NULL; + locale_path_len = 0; + +- locpath_var = getenv ("LOCPATH"); ++ locpath_var = __secure_getenv ("LOCPATH"); + if (locpath_var != NULL && locpath_var[0] != '\0') + { + if (__argz_create_sep (locpath_var, ':', +diff -Naur glibc-2.8-20080929.orig/malloc/arena.c glibc-2.8-20080929/malloc/arena.c +--- glibc-2.8-20080929.orig/malloc/arena.c 2007-12-12 00:11:27.000000000 +0000 ++++ glibc-2.8-20080929/malloc/arena.c 2008-10-15 00:30:49.000000000 +0000 +@@ -494,10 +494,10 @@ + # undef NO_STARTER + # endif + #endif ++ s = NULL; + #ifdef _LIBC + secure = __libc_enable_secure; +- s = NULL; +- if (__builtin_expect (_environ != NULL, 1)) ++ if (! secure && __builtin_expect (_environ != NULL, 1)) + { + char **runp = _environ; + char *envline; +@@ -520,26 +520,20 @@ + s = &envline[7]; + break; + case 8: +- if (! secure) +- { + if (memcmp (envline, "TOP_PAD_", 8) == 0) + mALLOPt(M_TOP_PAD, atoi(&envline[9])); + else if (memcmp (envline, "PERTURB_", 8) == 0) + mALLOPt(M_PERTURB, atoi(&envline[9])); +- } + break; + case 9: +- if (! secure && memcmp (envline, "MMAP_MAX_", 9) == 0) ++ if (memcmp (envline, "MMAP_MAX_", 9) == 0) + mALLOPt(M_MMAP_MAX, atoi(&envline[10])); + break; + case 15: +- if (! secure) +- { + if (memcmp (envline, "TRIM_THRESHOLD_", 15) == 0) + mALLOPt(M_TRIM_THRESHOLD, atoi(&envline[16])); + else if (memcmp (envline, "MMAP_THRESHOLD_", 15) == 0) + mALLOPt(M_MMAP_THRESHOLD, atoi(&envline[16])); +- } + break; + default: + break; +diff -Naur glibc-2.8-20080929.orig/malloc/memusage.c glibc-2.8-20080929/malloc/memusage.c +--- glibc-2.8-20080929.orig/malloc/memusage.c 2006-12-08 17:13:24.000000000 +0000 ++++ glibc-2.8-20080929/malloc/memusage.c 2008-10-15 00:30:49.000000000 +0000 +@@ -214,7 +214,7 @@ + static void + me (void) + { +- const char *env = getenv ("MEMUSAGE_PROG_NAME"); ++ const char *env = __secure_getenv ("MEMUSAGE_PROG_NAME"); + size_t prog_len = strlen (__progname); + + initialized = -1; +@@ -250,7 +250,7 @@ + if (!start_sp) + start_sp = GETSP (); + +- outname = getenv ("MEMUSAGE_OUTPUT"); ++ outname = __secure_getenv ("MEMUSAGE_OUTPUT"); + if (outname != NULL && outname[0] != '\0' + && (access (outname, R_OK | W_OK) == 0 || errno == ENOENT)) + { +@@ -273,7 +273,7 @@ + /* Determine the buffer size. We use the default if the + environment variable is not present. */ + buffer_size = DEFAULT_BUFFER_SIZE; +- if (getenv ("MEMUSAGE_BUFFER_SIZE") != NULL) ++ if (__secure_getenv ("MEMUSAGE_BUFFER_SIZE") != NULL) + { + buffer_size = atoi (getenv ("MEMUSAGE_BUFFER_SIZE")); + if (buffer_size == 0 || buffer_size > DEFAULT_BUFFER_SIZE) +@@ -281,7 +281,7 @@ + } + + /* Possibly enable timer-based stack pointer retrieval. */ +- if (getenv ("MEMUSAGE_NO_TIMER") == NULL) ++ if (__secure_getenv ("MEMUSAGE_NO_TIMER") == NULL) + { + struct sigaction act; + +@@ -302,7 +302,7 @@ + } + } + +- if (!not_me && getenv ("MEMUSAGE_TRACE_MMAP") != NULL) ++ if (!not_me && __secure_getenv ("MEMUSAGE_TRACE_MMAP") != NULL) + trace_mmap = true; + } + } +diff -Naur glibc-2.8-20080929.orig/nis/nis_defaults.c glibc-2.8-20080929/nis/nis_defaults.c +--- glibc-2.8-20080929.orig/nis/nis_defaults.c 2006-10-11 16:22:34.000000000 +0000 ++++ glibc-2.8-20080929/nis/nis_defaults.c 2008-10-15 00:30:49.000000000 +0000 +@@ -358,7 +358,7 @@ + + char *cptr = defaults; + if (cptr == NULL) +- cptr = getenv ("NIS_DEFAULTS"); ++ cptr = __secure_getenv ("NIS_DEFAULTS"); + + if (cptr != NULL) + { +@@ -385,7 +385,7 @@ + + char *cptr = defaults; + if (cptr == NULL) +- cptr = getenv ("NIS_DEFAULTS"); ++ cptr = __secure_getenv ("NIS_DEFAULTS"); + + if (cptr != NULL) + { +@@ -417,7 +417,7 @@ + return searchttl (defaults); + } + +- cptr = getenv ("NIS_DEFAULTS"); ++ cptr = __secure_getenv ("NIS_DEFAULTS"); + if (cptr == NULL) + return DEFAULT_TTL; + +@@ -445,7 +445,7 @@ + result = searchaccess (param, result); + else + { +- cptr = getenv ("NIS_DEFAULTS"); ++ cptr = __secure_getenv ("NIS_DEFAULTS"); + if (cptr != NULL && strstr (cptr, "access=") != NULL) + result = searchaccess (cptr, result); + } +diff -Naur glibc-2.8-20080929.orig/nis/nis_local_names.c glibc-2.8-20080929/nis/nis_local_names.c +--- glibc-2.8-20080929.orig/nis/nis_local_names.c 2006-04-07 06:52:01.000000000 +0000 ++++ glibc-2.8-20080929/nis/nis_local_names.c 2008-10-15 00:30:49.000000000 +0000 +@@ -30,7 +30,7 @@ + + char *cptr; + if (__nisgroup[0] == '\0' +- && (cptr = getenv ("NIS_GROUP")) != NULL ++ && (cptr = __secure_getenv ("NIS_GROUP")) != NULL + && strlen (cptr) < NIS_MAXNAMELEN) + { + char *cp = stpcpy (__nisgroup, cptr); +diff -Naur glibc-2.8-20080929.orig/nis/nis_subr.c glibc-2.8-20080929/nis/nis_subr.c +--- glibc-2.8-20080929.orig/nis/nis_subr.c 2007-07-28 20:43:36.000000000 +0000 ++++ glibc-2.8-20080929/nis/nis_subr.c 2008-10-15 00:30:49.000000000 +0000 +@@ -178,7 +178,7 @@ + } + + /* Get the search path, where we have to search "name" */ +- path = getenv ("NIS_PATH"); ++ path = __secure_getenv ("NIS_PATH"); + if (path == NULL) + path = strdupa ("$"); + else +diff -Naur glibc-2.8-20080929.orig/posix/execvp.c glibc-2.8-20080929/posix/execvp.c +--- glibc-2.8-20080929.orig/posix/execvp.c 2007-01-03 23:01:15.000000000 +0000 ++++ glibc-2.8-20080929/posix/execvp.c 2008-10-15 00:30:49.000000000 +0000 +@@ -90,7 +90,7 @@ + { + size_t pathlen; + size_t alloclen = 0; +- char *path = getenv ("PATH"); ++ char *path = __secure_getenv ("PATH"); + if (path == NULL) + { + pathlen = confstr (_CS_PATH, (char *) NULL, 0); +@@ -116,11 +116,11 @@ + if (path == NULL) + { + /* There is no `PATH' in the environment. +- The default search path is the current directory +- followed by the path `confstr' returns for `_CS_PATH'. */ ++ The default search path is what `confstr' returns ++ for `_CS_PATH'. */ + path = name + pathlen + len + 1; +- path[0] = ':'; +- (void) confstr (_CS_PATH, path + 1, pathlen); ++ path[0] = '\0'; ++ (void) confstr (_CS_PATH, path, pathlen); + } + + /* Copy the file name at the top. */ +diff -Naur glibc-2.8-20080929.orig/posix/glob.c glibc-2.8-20080929/posix/glob.c +--- glibc-2.8-20080929.orig/posix/glob.c 2007-10-15 04:59:03.000000000 +0000 ++++ glibc-2.8-20080929/posix/glob.c 2008-10-15 00:30:49.000000000 +0000 +@@ -557,7 +557,7 @@ + && (dirname[2] == '\0' || dirname[2] == '/'))) + { + /* Look up home directory. */ +- const char *home_dir = getenv ("HOME"); ++ const char *home_dir = __secure_getenv ("HOME"); + # ifdef _AMIGA + if (home_dir == NULL || home_dir[0] == '\0') + home_dir = "SYS:"; +diff -Naur glibc-2.8-20080929.orig/posix/wordexp.c glibc-2.8-20080929/posix/wordexp.c +--- glibc-2.8-20080929.orig/posix/wordexp.c 2007-01-25 00:43:39.000000000 +0000 ++++ glibc-2.8-20080929/posix/wordexp.c 2008-10-15 00:30:49.000000000 +0000 +@@ -320,7 +320,7 @@ + results are unspecified. We do a lookup on the uid if + HOME is unset. */ + +- home = getenv ("HOME"); ++ home = __secure_getenv ("HOME"); + if (home != NULL) + { + *word = w_addstr (*word, word_length, max_length, home); +@@ -1493,7 +1493,7 @@ + } + } + else +- value = getenv (env); ++ value = __secure_getenv (env); + + if (value == NULL && (flags & WRDE_UNDEF)) + { +@@ -2262,7 +2262,7 @@ + /* Find out what the field separators are. + * There are two types: whitespace and non-whitespace. + */ +- ifs = getenv ("IFS"); ++ ifs = __secure_getenv ("IFS"); + + if (ifs == NULL) + /* IFS unset - use . */ +diff -Naur glibc-2.8-20080929.orig/resolv/res_hconf.c glibc-2.8-20080929/resolv/res_hconf.c +--- glibc-2.8-20080929.orig/resolv/res_hconf.c 2007-11-23 03:03:31.000000000 +0000 ++++ glibc-2.8-20080929/resolv/res_hconf.c 2008-10-15 00:30:49.000000000 +0000 +@@ -304,7 +304,7 @@ + + memset (&_res_hconf, '\0', sizeof (_res_hconf)); + +- hconf_name = getenv (ENV_HOSTCONF); ++ hconf_name = __secure_getenv (ENV_HOSTCONF); + if (hconf_name == NULL) + hconf_name = _PATH_HOSTCONF; + +@@ -323,23 +323,23 @@ + fclose (fp); + } + +- envval = getenv (ENV_SPOOF); ++ envval = __secure_getenv (ENV_SPOOF); + if (envval) + arg_spoof (ENV_SPOOF, 1, envval); + +- envval = getenv (ENV_MULTI); ++ envval = __secure_getenv (ENV_MULTI); + if (envval) + arg_bool (ENV_MULTI, 1, envval, HCONF_FLAG_MULTI); + +- envval = getenv (ENV_REORDER); ++ envval = __secure_getenv (ENV_REORDER); + if (envval) + arg_bool (ENV_REORDER, 1, envval, HCONF_FLAG_REORDER); + +- envval = getenv (ENV_TRIM_ADD); ++ envval = __secure_getenv (ENV_TRIM_ADD); + if (envval) + arg_trimdomain_list (ENV_TRIM_ADD, 1, envval); + +- envval = getenv (ENV_TRIM_OVERR); ++ envval = __secure_getenv (ENV_TRIM_OVERR); + if (envval) + { + _res_hconf.num_trimdomains = 0; +diff -Naur glibc-2.8-20080929.orig/resolv/res_init.c glibc-2.8-20080929/resolv/res_init.c +--- glibc-2.8-20080929.orig/resolv/res_init.c 2008-04-07 17:20:25.000000000 +0000 ++++ glibc-2.8-20080929/resolv/res_init.c 2008-10-15 00:30:49.000000000 +0000 +@@ -201,7 +201,7 @@ + #endif + + /* Allow user to override the local domain definition */ +- if ((cp = getenv("LOCALDOMAIN")) != NULL) { ++ if ((cp = __secure_getenv("LOCALDOMAIN")) != NULL) { + (void)strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1); + statp->defdname[sizeof(statp->defdname) - 1] = '\0'; + haveenv++; +@@ -470,7 +470,7 @@ + #endif /* !RFC1535 */ + } + +- if ((cp = getenv("RES_OPTIONS")) != NULL) ++ if ((cp = __secure_getenv("RES_OPTIONS")) != NULL) + res_setoptions(statp, cp, "env"); + statp->options |= RES_INIT; + return (0); +diff -Naur glibc-2.8-20080929.orig/resolv/res_query.c glibc-2.8-20080929/resolv/res_query.c +--- glibc-2.8-20080929.orig/resolv/res_query.c 2007-02-09 23:43:25.000000000 +0000 ++++ glibc-2.8-20080929/resolv/res_query.c 2008-10-15 00:30:49.000000000 +0000 +@@ -474,7 +474,7 @@ + + if (statp->options & RES_NOALIASES) + return (NULL); +- file = getenv("HOSTALIASES"); ++ file = __secure_getenv("HOSTALIASES"); + if (file == NULL || (fp = fopen(file, "r")) == NULL) + return (NULL); + setbuf(fp, NULL); +diff -Naur glibc-2.8-20080929.orig/stdlib/fmtmsg.c glibc-2.8-20080929/stdlib/fmtmsg.c +--- glibc-2.8-20080929.orig/stdlib/fmtmsg.c 2006-05-15 18:41:18.000000000 +0000 ++++ glibc-2.8-20080929/stdlib/fmtmsg.c 2008-10-15 00:30:49.000000000 +0000 +@@ -205,8 +205,8 @@ + static void + init (void) + { +- const char *msgverb_var = getenv ("MSGVERB"); +- const char *sevlevel_var = getenv ("SEV_LEVEL"); ++ const char *msgverb_var = __secure_getenv ("MSGVERB"); ++ const char *sevlevel_var = __secure_getenv ("SEV_LEVEL"); + + if (msgverb_var != NULL && msgverb_var[0] != '\0') + { +diff -Naur glibc-2.8-20080929.orig/sunrpc/rpc_svcout.c glibc-2.8-20080929/sunrpc/rpc_svcout.c +--- glibc-2.8-20080929.orig/sunrpc/rpc_svcout.c 2005-11-21 15:43:03.000000000 +0000 ++++ glibc-2.8-20080929/sunrpc/rpc_svcout.c 2008-10-15 00:30:49.000000000 +0000 +@@ -897,7 +897,7 @@ + f_print (fout, "\t\t_rpcpmstart = 1;\n"); + if (logflag) + open_log_file (infile, "\t\t"); +- f_print (fout, "\t\tif ((netid = getenv(\"NLSPROVIDER\")) == NULL) {\n"); ++ f_print (fout, "\t\tif ((netid = __secure_getenv(\"NLSPROVIDER\")) == NULL) {\n"); + sprintf (_errbuf, "cannot get transport name"); + print_err_message ("\t\t\t"); + f_print (fout, "\t\t} else if ((nconf = getnetconfigent(netid)) == NULL) {\n"); +diff -Naur glibc-2.8-20080929.orig/sysdeps/generic/unsecvars.h glibc-2.8-20080929/sysdeps/generic/unsecvars.h +--- glibc-2.8-20080929.orig/sysdeps/generic/unsecvars.h 2006-10-11 16:24:05.000000000 +0000 ++++ glibc-2.8-20080929/sysdeps/generic/unsecvars.h 2008-10-15 00:32:09.000000000 +0000 +@@ -2,25 +2,87 @@ + all stuffed in a single string which means they have to be terminated + with a '\0' explicitly. */ + #define UNSECURE_ENVVARS \ +- "GCONV_PATH\0" \ +- "GETCONF_DIR\0" \ +- "HOSTALIASES\0" \ +- "LD_AUDIT\0" \ +- "LD_DEBUG\0" \ +- "LD_DEBUG_OUTPUT\0" \ +- "LD_DYNAMIC_WEAK\0" \ +- "LD_LIBRARY_PATH\0" \ +- "LD_ORIGIN_PATH\0" \ +- "LD_PRELOAD\0" \ +- "LD_PROFILE\0" \ +- "LD_SHOW_AUXV\0" \ +- "LD_USE_LOAD_BIAS\0" \ +- "LOCALDOMAIN\0" \ +- "LOCPATH\0" \ +- "MALLOC_TRACE\0" \ +- "NIS_PATH\0" \ +- "NLSPATH\0" \ +- "RESOLV_HOST_CONF\0" \ +- "RES_OPTIONS\0" \ +- "TMPDIR\0" \ ++ "ARGP_HELP_FMT\0" \ ++ "DATEMSK\0" \ ++ "GCONV_PATH\0" \ ++ "GETCONF_DIR\0" \ ++ "GMON_OUT_PREFIX\0" \ ++ "HESIOD_CONFIG\0" \ ++ "HES_DOMAIN\0" \ ++ "HOSTALIASES\0" \ ++ "LD_AUDIT\0" \ ++ "LD_BIND_NOT\0" \ ++ "LD_BIND_NOW\0" \ ++ "LD_DEBUG\0" \ ++ "LD_DEBUG_OUTPUT\0" \ ++ "LD_DYNAMIC_WEAK\0" \ ++ "LD_HWCAP_MASK\0" \ ++ "LD_LIBRARY_PATH\0" \ ++ "LD_ORIGIN_PATH\0" \ ++ "LD_POINTER_GUARD\0" \ ++ "LD_PRELOAD\0" \ ++ "LD_PROFILE\0" \ ++ "LD_PROFILE_OUTPUT\0" \ ++ "LD_SHOW_AUXV\0" \ ++ "LD_TRACE_LOADED_OBJECTS\0" \ ++ "LD_TRACE_PRELINKING\0" \ ++ "LD_USE_LOAD_BIAS\0" \ ++ "LD_VERBOSE\0" \ ++ "LD_WARN\0" \ ++ "LOCALDOMAIN\0" \ ++ "LOCPATH\0" \ ++ "MALLOC_CHECK_\0" \ ++ "MALLOC_MMAP_MAX_\0" \ ++ "MALLOC_MMAP_THRESHOLD_\0" \ ++ "MALLOC_PERTURB_\0" \ ++ "MALLOC_TOP_PAD_\0" \ ++ "MALLOC_TRACE\0" \ ++ "MALLOC_TRIM_THRESHOLD_\0" \ ++ "MEMUSAGE_BUFFER_SIZE\0" \ ++ "MEMUSAGE_NO_TIMER\0" \ ++ "MEMUSAGE_OUTPUT\0" \ ++ "MEMUSAGE_PROG_NAME\0" \ ++ "MEMUSAGE_TRACE_MMAP\0" \ ++ "MSGVERB\0" \ ++ "MUDFLAP_OPTIONS\0" \ ++ "NIS_DEFAULTS\0" \ ++ "NIS_GROUP\0" \ ++ "NIS_PATH\0" \ ++ "NLSPATH\0" \ ++ "PCPROFILE_OUTPUT\0" \ ++ "POSIXLY_CORRECT\0" \ ++ "PWD\0" \ ++ "RESOLV_ADD_TRIM_DOMAINS\0" \ ++ "RESOLV_HOST_CONF\0" \ ++ "RESOLV_MULTI\0" \ ++ "RESOLV_OVERRIDE_TRIM_DOMAINS\0" \ ++ "RESOLV_REORDER\0" \ ++ "RESOLV_SPOOF_CHECK\0" \ ++ "RES_OPTIONS\0" \ ++ "SEGFAULT_OUTPUT_NAME\0" \ ++ "SEGFAULT_SIGNALS\0" \ ++ "SEGFAULT_USE_ALTSTACK\0" \ ++ "SEV_LEVEL\0" \ ++ "TZ\0" \ + "TZDIR\0" ++ ++#define UNSECURE_UID_ENVVARS \ ++ "TMPDIR\0" ++ ++#define RESTRICTED_ENVVARS \ ++ "LANG\0" \ ++ "LANGUAGE\0" \ ++ "LC_ADDRESS\0" \ ++ "LC_ALL\0" \ ++ "LC_COLLATE\0" \ ++ "LC_CTYPE\0" \ ++ "LC_IDENTIFICATION\0" \ ++ "LC_MEASUREMENT\0" \ ++ "LC_MESSAGES\0" \ ++ "LC_MONETARY\0" \ ++ "LC_NAME\0" \ ++ "LC_NUMERIC\0" \ ++ "LC_PAPER\0" \ ++ "LC_TELEPHONE\0" \ ++ "LC_TIME\0" \ ++ "LC_XXX\0" +diff -Naur glibc-2.8-20080929.orig/sysdeps/posix/spawni.c glibc-2.8-20080929/sysdeps/posix/spawni.c +--- glibc-2.8-20080929.orig/sysdeps/posix/spawni.c 2006-06-04 22:16:05.000000000 +0000 ++++ glibc-2.8-20080929/sysdeps/posix/spawni.c 2008-10-15 00:30:49.000000000 +0000 +@@ -227,16 +227,15 @@ + } + + /* We have to search for FILE on the path. */ +- path = getenv ("PATH"); ++ path = __secure_getenv ("PATH"); + if (path == NULL) + { + /* There is no `PATH' in the environment. +- The default search path is the current directory +- followed by the path `confstr' returns for `_CS_PATH'. */ ++ The default search path is ehat `confstr' returns ++ for `_CS_PATH'. */ + len = confstr (_CS_PATH, (char *) NULL, 0); +- path = (char *) __alloca (1 + len); +- path[0] = ':'; +- (void) confstr (_CS_PATH, path + 1, len); ++ path = (char *) __alloca (len); ++ (void) confstr (_CS_PATH, path, len); + } + + len = strlen (file) + 1; +diff -Naur glibc-2.8-20080929.orig/sysdeps/unix/sysv/linux/dl-librecon.h glibc-2.8-20080929/sysdeps/unix/sysv/linux/dl-librecon.h +--- glibc-2.8-20080929.orig/sysdeps/unix/sysv/linux/dl-librecon.h 2004-03-05 10:14:48.000000000 +0000 ++++ glibc-2.8-20080929/sysdeps/unix/sysv/linux/dl-librecon.h 2008-10-15 00:30:49.000000000 +0000 +@@ -53,7 +53,7 @@ + + #define DL_OSVERSION_INIT \ + do { \ +- char *assume_kernel = getenv ("LD_ASSUME_KERNEL"); \ ++ char *assume_kernel = __secure_getenv ("LD_ASSUME_KERNEL"); \ + if (assume_kernel) \ + _dl_osversion_init (assume_kernel); \ + } while (0) +diff -Naur glibc-2.8-20080929.orig/sysdeps/unix/sysv/linux/i386/dl-librecon.h glibc-2.8-20080929/sysdeps/unix/sysv/linux/i386/dl-librecon.h +--- glibc-2.8-20080929.orig/sysdeps/unix/sysv/linux/i386/dl-librecon.h 2004-10-14 01:53:55.000000000 +0000 ++++ glibc-2.8-20080929/sysdeps/unix/sysv/linux/i386/dl-librecon.h 2008-10-15 00:30:49.000000000 +0000 +@@ -57,6 +57,7 @@ + /* Extra unsecure variables. The names are all stuffed in a single + string which means they have to be terminated with a '\0' explicitly. */ + #define EXTRA_UNSECURE_ENVVARS \ ++ "LD_LIBRARY_VERSION\0" \ + "LD_AOUT_LIBRARY_PATH\0" \ + "LD_AOUT_PRELOAD\0" + +diff -Naur glibc-2.8-20080929.orig/time/getdate.c glibc-2.8-20080929/time/getdate.c +--- glibc-2.8-20080929.orig/time/getdate.c 2007-12-10 01:40:43.000000000 +0000 ++++ glibc-2.8-20080929/time/getdate.c 2008-10-15 00:30:49.000000000 +0000 +@@ -115,7 +115,7 @@ + struct stat64 st; + int mday_ok = 0; + +- datemsk = getenv ("DATEMSK"); ++ datemsk = __secure_getenv ("DATEMSK"); + if (datemsk == NULL || *datemsk == '\0') + return 1; + +diff -Naur glibc-2.8-20080929.orig/time/tzfile.c glibc-2.8-20080929/time/tzfile.c +--- glibc-2.8-20080929.orig/time/tzfile.c 2007-11-06 01:03:43.000000000 +0000 ++++ glibc-2.8-20080929/time/tzfile.c 2008-10-15 00:30:49.000000000 +0000 +@@ -149,7 +149,7 @@ + unsigned int len, tzdir_len; + char *new, *tmp; + +- tzdir = getenv ("TZDIR"); ++ tzdir = __secure_getenv ("TZDIR"); + if (tzdir == NULL || *tzdir == '\0') + { + tzdir = default_tzdir; +diff -Naur glibc-2.8-20080929.orig/time/tzset.c glibc-2.8-20080929/time/tzset.c +--- glibc-2.8-20080929.orig/time/tzset.c 2008-03-19 06:43:34.000000000 +0000 ++++ glibc-2.8-20080929/time/tzset.c 2008-10-15 00:30:49.000000000 +0000 +@@ -383,8 +383,11 @@ + return; + is_initialized = 1; + +- /* Examine the TZ environment variable. */ +- tz = getenv ("TZ"); ++ /* Examine the TZ environment variable. This doesn't really have to be ++ a __secure_getenv() call as __tzfile_read() tries to only read files ++ found under a trusted directory, but this helps reduce the amount of ++ security-critical code. */ ++ tz = __secure_getenv ("TZ"); + if (tz == NULL && !explicit) + /* Use the site-wide default. This is a file name which means we + would not see changes to the file if we compare only the file diff --git a/pkgs/core/glibc/patches/glibc-2.10.1-strlcpy_strlcat-1.patch b/pkgs/core/glibc/patches/glibc-2.10.1-strlcpy_strlcat-1.patch new file mode 100644 index 000000000..5cbacbfdb --- /dev/null +++ b/pkgs/core/glibc/patches/glibc-2.10.1-strlcpy_strlcat-1.patch @@ -0,0 +1,349 @@ +diff -Naur glibc-2.7.orig/manual/strlcpy.3 glibc-2.7/manual/strlcpy.3 +--- glibc-2.7.orig/manual/strlcpy.3 1970-01-01 00:00:00.000000000 +0000 ++++ glibc-2.7/manual/strlcpy.3 2008-01-19 23:13:56.000000000 +0000 +@@ -0,0 +1,186 @@ ++.\" $OpenBSD: strlcpy.3,v 1.18 2005/08/06 03:24:19 jaredy Exp $ ++.\" ++.\" Copyright (c) 1998, 2000 Todd C. Miller ++.\" ++.\" Permission to use, copy, modify, and distribute this software for any ++.\" purpose with or without fee is hereby granted, provided that the above ++.\" copyright notice and this permission notice appear in all copies. ++.\" ++.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++.\" ++.Dd June 22, 1998 ++.Dt STRLCPY 3 ++.Os ++.Sh NAME ++.Nm strlcpy , ++.Nm strlcat ++.Nd size-bounded string copying and concatenation ++.Sh SYNOPSIS ++.Fd #include ++.Ft size_t ++.Fn strlcpy "char *dst" "const char *src" "size_t size" ++.Ft size_t ++.Fn strlcat "char *dst" "const char *src" "size_t size" ++.Sh DESCRIPTION ++The ++.Fn strlcpy ++and ++.Fn strlcat ++functions copy and concatenate strings respectively. ++They are designed ++to be safer, more consistent, and less error prone replacements for ++.Xr strncpy 3 ++and ++.Xr strncat 3 . ++Unlike those functions, ++.Fn strlcpy ++and ++.Fn strlcat ++take the full size of the buffer (not just the length) and guarantee to ++NUL-terminate the result (as long as ++.Fa size ++is larger than 0 or, in the case of ++.Fn strlcat , ++as long as there is at least one byte free in ++.Fa dst ) . ++Note that a byte for the NUL should be included in ++.Fa size . ++Also note that ++.Fn strlcpy ++and ++.Fn strlcat ++only operate on true ++.Dq C ++strings. ++This means that for ++.Fn strlcpy ++.Fa src ++must be NUL-terminated and for ++.Fn strlcat ++both ++.Fa src ++and ++.Fa dst ++must be NUL-terminated. ++.Pp ++The ++.Fn strlcpy ++function copies up to ++.Fa size ++- 1 characters from the NUL-terminated string ++.Fa src ++to ++.Fa dst , ++NUL-terminating the result. ++.Pp ++The ++.Fn strlcat ++function appends the NUL-terminated string ++.Fa src ++to the end of ++.Fa dst . ++It will append at most ++.Fa size ++- strlen(dst) - 1 bytes, NUL-terminating the result. ++.Sh RETURN VALUES ++The ++.Fn strlcpy ++and ++.Fn strlcat ++functions return the total length of the string they tried to create. ++For ++.Fn strlcpy ++that means the length of ++.Fa src . ++For ++.Fn strlcat ++that means the initial length of ++.Fa dst ++plus ++the length of ++.Fa src . ++While this may seem somewhat confusing, it was done to make ++truncation detection simple. ++.Pp ++Note, however, that if ++.Fn strlcat ++traverses ++.Fa size ++characters without finding a NUL, the length of the string is considered ++to be ++.Fa size ++and the destination string will not be NUL-terminated (since there was ++no space for the NUL). ++This keeps ++.Fn strlcat ++from running off the end of a string. ++In practice this should not happen (as it means that either ++.Fa size ++is incorrect or that ++.Fa dst ++is not a proper ++.Dq C ++string). ++The check exists to prevent potential security problems in incorrect code. ++.Sh EXAMPLES ++The following code fragment illustrates the simple case: ++.Bd -literal -offset indent ++char *s, *p, buf[BUFSIZ]; ++ ++\&... ++ ++(void)strlcpy(buf, s, sizeof(buf)); ++(void)strlcat(buf, p, sizeof(buf)); ++.Ed ++.Pp ++To detect truncation, perhaps while building a pathname, something ++like the following might be used: ++.Bd -literal -offset indent ++char *dir, *file, pname[MAXPATHLEN]; ++ ++\&... ++ ++if (strlcpy(pname, dir, sizeof(pname)) >= sizeof(pname)) ++ goto toolong; ++if (strlcat(pname, file, sizeof(pname)) >= sizeof(pname)) ++ goto toolong; ++.Ed ++.Pp ++Since it is known how many characters were copied the first time, things ++can be sped up a bit by using a copy instead of an append: ++.Bd -literal -offset indent ++char *dir, *file, pname[MAXPATHLEN]; ++size_t n; ++ ++\&... ++ ++n = strlcpy(pname, dir, sizeof(pname)); ++if (n >= sizeof(pname)) ++ goto toolong; ++if (strlcpy(pname + n, file, sizeof(pname) - n) >= sizeof(pname) - n) ++ goto toolong; ++.Ed ++.Pp ++However, one may question the validity of such optimizations, as they ++defeat the whole purpose of ++.Fn strlcpy ++and ++.Fn strlcat . ++As a matter of fact, the first version of this manual page got it wrong. ++.Sh SEE ALSO ++.Xr snprintf 3 , ++.Xr strncat 3 , ++.Xr strncpy 3 ++.Sh HISTORY ++The ++.Fn strlcpy ++and ++.Fn strlcat ++functions first appeared in ++.Ox 2.4 . +diff -Naur glibc-2.7.orig/string/Makefile glibc-2.7/string/Makefile +--- glibc-2.7.orig/string/Makefile 2007-02-01 16:10:11.000000000 +0000 ++++ glibc-2.7/string/Makefile 2008-01-19 23:14:48.000000000 +0000 +@@ -40,7 +40,12 @@ + addsep replace) \ + envz basename \ + strcoll_l strxfrm_l string-inlines memrchr \ +- xpg-strerror strerror_l ++ xpg-strerror strerror_l strlcat strlcpy ++ ++# These routines will be omitted from the libc shared object. ++# Instead the static object files will be included in a special archive ++# linked against when the shared library will be used. ++static-only-routines = strlcat strlcpy + + # Gcc internally generates calls to unbounded memcpy and memset + # for -fbounded-pointer compiles. Glibc uses memchr for explicit checks. +diff -Naur glibc-2.7.orig/string/string.h glibc-2.7/string/string.h +--- glibc-2.7.orig/string/string.h 2007-09-15 02:35:08.000000000 +0000 ++++ glibc-2.7/string/string.h 2008-01-19 23:13:56.000000000 +0000 +@@ -354,6 +354,24 @@ + extern char *strsep (char **__restrict __stringp, + __const char *__restrict __delim) + __THROW __nonnull ((1, 2)); ++ ++/* ++ * Appends __src to string __dst of size __n (unlike strncat, __n is the ++ * full size of __dst, not space left). At most __n-1 characters ++ * will be copied. Always NUL terminates (unless __n <= strlen(__dst)). ++ * Returns strlen(__src) + MIN(__n, strlen(initial __dst)). ++ * If retval >= __n, truncation occurred. ++ */ ++extern size_t strlcat (char *__dst, __const char *__src, size_t __n) ++ __THROW __nonnull ((1, 2)); ++ ++/* ++ * Copy __src to string __dst of size __n. At most __n-1 characters ++ * will be copied. Always NUL terminates (unless __n == 0). ++ * Returns strlen(__src); if retval >= __n, truncation occurred. ++ */ ++extern size_t strlcpy (char *__dst, __const char *__src, size_t __n) ++ __THROW __nonnull ((1, 2)); + #endif + + #ifdef __USE_GNU +diff -Naur glibc-2.7.orig/string/strlcat.c glibc-2.7/string/strlcat.c +--- glibc-2.7.orig/string/strlcat.c 1970-01-01 00:00:00.000000000 +0000 ++++ glibc-2.7/string/strlcat.c 2008-01-19 23:13:56.000000000 +0000 +@@ -0,0 +1,55 @@ ++/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */ ++ ++/* ++ * Copyright (c) 1998 Todd C. Miller ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#include ++#include ++ ++/* ++ * Appends src to string dst of size siz (unlike strncat, siz is the ++ * full size of dst, not space left). At most siz-1 characters ++ * will be copied. Always NUL terminates (unless siz <= strlen(dst)). ++ * Returns strlen(src) + MIN(siz, strlen(initial dst)). ++ * If retval >= siz, truncation occurred. ++ */ ++size_t ++strlcat(char *dst, const char *src, size_t siz) ++{ ++ char *d = dst; ++ const char *s = src; ++ size_t n = siz; ++ size_t dlen; ++ ++ /* Find the end of dst and adjust bytes left but don't go past end */ ++ while (n-- != 0 && *d != '\0') ++ d++; ++ dlen = d - dst; ++ n = siz - dlen; ++ ++ if (n == 0) ++ return(dlen + strlen(s)); ++ while (*s != '\0') { ++ if (n != 1) { ++ *d++ = *s; ++ n--; ++ } ++ s++; ++ } ++ *d = '\0'; ++ ++ return(dlen + (s - src)); /* count does not include NUL */ ++} +diff -Naur glibc-2.7.orig/string/strlcpy.c glibc-2.7/string/strlcpy.c +--- glibc-2.7.orig/string/strlcpy.c 1970-01-01 00:00:00.000000000 +0000 ++++ glibc-2.7/string/strlcpy.c 2008-01-19 23:13:56.000000000 +0000 +@@ -0,0 +1,51 @@ ++/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */ ++ ++/* ++ * Copyright (c) 1998 Todd C. Miller ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#include ++#include ++ ++/* ++ * Copy src to string dst of size siz. At most siz-1 characters ++ * will be copied. Always NUL terminates (unless siz == 0). ++ * Returns strlen(src); if retval >= siz, truncation occurred. ++ */ ++size_t ++strlcpy(char *dst, const char *src, size_t siz) ++{ ++ char *d = dst; ++ const char *s = src; ++ size_t n = siz; ++ ++ /* Copy as many bytes as will fit */ ++ if (n != 0) { ++ while (--n != 0) { ++ if ((*d++ = *s++) == '\0') ++ break; ++ } ++ } ++ ++ /* Not enough room in dst, add NUL and traverse rest of src */ ++ if (n == 0) { ++ if (siz != 0) ++ *d = '\0'; /* NUL-terminate dst */ ++ while (*s++) ++ ; ++ } ++ ++ return(s - src - 1); /* count does not include NUL */ ++} diff --git a/pkgs/core/glibc/patches/glibc-2.10.1-undefine-__i686.patch b/pkgs/core/glibc/patches/glibc-2.10.1-undefine-__i686.patch new file mode 100644 index 000000000..ce0ebd404 --- /dev/null +++ b/pkgs/core/glibc/patches/glibc-2.10.1-undefine-__i686.patch @@ -0,0 +1,44 @@ +If gcc is configured to generate i686 code or better by default (like +when using the --with-arch=pentium3 configure option), then the __i686 +macro will always be defined automatically and thus screw up the +compilation of some .S files. +http://bugs.gentoo.org/131108 + +2006-04-25 Mike Frysinger + + * sysdeps/i386/sysdep.h (__i686): Undefine. + +--- glibc-2.10.1/sysdeps/i386/sysdep.h ++++ glibc-2.10.1/sysdeps/i386/sysdep.h +@@ -17,6 +17,14 @@ + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + ++/* ++ * When building for i686 targets or better, gcc automatically defines ++ * '__i686' to '1' for us which causes trouble when using section names ++ * like '__i686.get_pc_thunk.reg'. Since we check for __i686__ in the ++ * code, killing '__i686' shouldn't be a problem. ++ */ ++#undef __i686 ++ + #include + + #ifdef __ASSEMBLER__ + +2006-04-25 Mike Frysinger + + * sysdeps/pthread/pt-initfini.c: Include sysdep.h. + +--- glibc-2.10.1/nptl/sysdeps/pthread/pt-initfini.c ++++ glibc-2.10.1/nptl/sysdeps/pthread/pt-initfini.c +@@ -45,6 +45,9 @@ + /* Embed an #include to pull in the alignment and .end directives. */ + asm ("\n#include \"defs.h\""); + ++/* Embed an #include to pull in asm settings. */ ++asm ("\n#include "); ++ + /* The initial common code ends here. */ + asm ("\n/*@HEADER_ENDS*/"); +