]> git.ipfire.org Git - ipfire-3.x.git/commitdiff
glibc: Copy patch files into repository.
authorMichael Tremer <michael.tremer@ipfire.org>
Sun, 7 Feb 2010 14:54:08 +0000 (15:54 +0100)
committerMichael Tremer <michael.tremer@ipfire.org>
Sun, 7 Feb 2010 14:54:08 +0000 (15:54 +0100)
15 files changed:
pkgs/core/glibc/glibc.nm
pkgs/core/glibc/patches/glibc-2.10.1-arc4random.patch [new file with mode: 0644]
pkgs/core/glibc/patches/glibc-2.10.1-asprintf_reset2null-1.patch [new file with mode: 0644]
pkgs/core/glibc/patches/glibc-2.10.1-hardened-configure-picdefault.patch [new file with mode: 0644]
pkgs/core/glibc/patches/glibc-2.10.1-hardened-inittls-nosysenter.patch [new file with mode: 0644]
pkgs/core/glibc/patches/glibc-2.10.1-hardened-pie.patch [new file with mode: 0644]
pkgs/core/glibc/patches/glibc-2.10.1-issetugid-1.patch [new file with mode: 0644]
pkgs/core/glibc/patches/glibc-2.10.1-localedef_trampoline-1.patch [new file with mode: 0644]
pkgs/core/glibc/patches/glibc-2.10.1-mktemp_urandom.patch [new file with mode: 0644]
pkgs/core/glibc/patches/glibc-2.10.1-pt_pax-1.patch [new file with mode: 0644]
pkgs/core/glibc/patches/glibc-2.10.1-res_randomid.patch [new file with mode: 0644]
pkgs/core/glibc/patches/glibc-2.10.1-resolv_response_length.patch [new file with mode: 0644]
pkgs/core/glibc/patches/glibc-2.10.1-sanitize_env.patch [new file with mode: 0644]
pkgs/core/glibc/patches/glibc-2.10.1-strlcpy_strlcat-1.patch [new file with mode: 0644]
pkgs/core/glibc/patches/glibc-2.10.1-undefine-__i686.patch [new file with mode: 0644]

index bcac591d0d55089bd4415b2f89e4f34290d1bbb8..9819c0d55809ec3e8fd4d30967361900d6e38acb 100644 (file)
@@ -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 (file)
index 0000000..c877c8c
--- /dev/null
@@ -0,0 +1,541 @@
+Submitted By: Robert Connolly <robert at linuxfromscratch dot org> (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 <stdlib.h>
++.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 <stdlib.h>
++#include <stdio.h>
++
++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 <dm@lcs.mit.edu>.
++ *
++ * 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 <fcntl.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <sys/types.h>
++#include <sys/param.h>
++#include <sys/time.h>
++#include <sys/sysctl.h>
++
++#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 <stdlib.h>
++#include <stdio.h>
++
++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 <dm@lcs.mit.edu>.
++ *
++ * 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 <fcntl.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <sys/types.h>
++#include <sys/param.h>
++#include <sys/time.h>
++#include <sys/sysctl.h>
++
++#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 <stdlib.h>
++#include <stdio.h>
++
++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 (file)
index 0000000..60dd425
--- /dev/null
@@ -0,0 +1,59 @@
+Submitted By: Robert Connolly <robert at linuxfromscratch dot org> (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 <ldv@altlinux.org>
+
+       * 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 (file)
index 0000000..19f2544
--- /dev/null
@@ -0,0 +1,29 @@
+Prevent default-fPIE from confusing configure into thinking
+PIC code is default.  This causes glibc to build both PIC and
+non-PIC code as normal, which on the hardened compiler generates
+PIC and PIE.
+
+Patch by Kevin F. Quinn <kevquinn@gentoo.org>
+
+--- 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 (file)
index 0000000..ce9c907
--- /dev/null
@@ -0,0 +1,273 @@
+When building glibc PIE (which is not something upstream support),
+several modifications are necessary to the glibc build process.
+
+First, any syscalls in PIEs must be of the PIC variant, otherwise
+textrels ensue.  Then, any syscalls made before the initialisation
+of the TLS will fail on i386, as the sysenter variant on i386 uses
+the TLS, giving rise to a chicken-and-egg situation.  This patch
+defines a PIC syscall variant that doesn't use sysenter, even when the sysenter
+version is normally used, and uses the non-sysenter version for the brk
+syscall that is performed by the TLS initialisation.  Further, the TLS
+initialisation is moved in this case prior to the initialisation of
+dl_osversion, as that requires further syscalls.
+
+csu/libc-start.c: Move initial TLS initialization to before the
+initialisation of dl_osversion, when INTERNAL_SYSCALL_NOSYSENTER is defined
+
+csu/libc-tls.c: Use the no-sysenter version of sbrk when
+INTERNAL_SYSCALL_NOSYSENTER is defined.
+
+misc/sbrk.c: Define a no-sysenter version of sbrk, using the no-sysenter
+version of brk - if INTERNAL_SYSCALL_NOSYSENTER is defined.
+
+misc/brk.c: Define a no-sysenter version of brk if
+INTERNAL_SYSCALL_NOSYSENTER is defined.
+
+sysdeps/unix/sysv/linux/i386/sysdep.h: Define INTERNAL_SYSCALL_NOSYSENTER
+Make INTERNAL_SYSCALL always use the PIC variant, even if not SHARED.
+
+Patch by Kevin F. Quinn <kevquinn@gentoo.org>
+
+--- 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 <tls.h>
++#include <sysdep.h>
+ #ifndef SHARED
+ # include <dl-osinfo.h>
+ extern void __pthread_initialize_minimal (void);
+@@ -129,6 +130,11 @@
+ #  endif
+   _dl_aux_init (auxvec);
+ # endif
++# ifdef INTERNAL_SYSCALL_NOSYSENTER
++  /* Do the initial TLS initialization before _dl_osversion,
++     since the latter uses the uname syscall.  */
++  __pthread_initialize_minimal ();
++# endif
+ # ifdef DL_SYSDEP_OSCHECK
+   if (!__libc_multiple_libcs)
+     {
+@@ -138,10 +144,12 @@
+     }
+ # endif
++# ifndef INTERNAL_SYSCALL_NOSYSENTER
+   /* Initialize the thread library at least a bit since the libgcc
+      functions are using thread functions if these are available and
+      we need to setup errno.  */
+   __pthread_initialize_minimal ();
++# endif
+   /* Set up the stack checker's canary.  */
+   uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard ();
+--- glibc-2.10.1/csu/libc-tls.c
++++ glibc-2.10.1/csu/libc-tls.c
+@@ -23,6 +23,7 @@
+ #include <unistd.h>
+ #include <stdio.h>
+ #include <sys/param.h>
++#include <sysdep.h>
+ #ifdef SHARED
+@@ -29,6 +30,9 @@
+  #error makefile bug, this file is for static only
+ #endif
++#ifdef INTERNAL_SYSCALL_NOSYSENTER
++extern void *__sbrk_nosysenter (intptr_t __delta);
++#endif
+ extern ElfW(Phdr) *_dl_phdr;
+ extern size_t _dl_phnum;
+@@ -141,14 +145,26 @@
+      The initialized value of _dl_tls_static_size is provided by dl-open.c
+      to request some surplus that permits dynamic loading of modules with
+-     IE-model TLS.  */
++     IE-model TLS.
++     
++     Where the normal sbrk would use a syscall that needs the TLS (i386)
++     use the special non-sysenter version instead.  */
+ #if TLS_TCB_AT_TP
+   tcb_offset = roundup (memsz + GL(dl_tls_static_size), tcbalign);
++# ifdef INTERNAL_SYSCALL_NOSYSENTER
++  tlsblock = __sbrk_nosysenter (tcb_offset + tcbsize + max_align);
++# else
+   tlsblock = __sbrk (tcb_offset + tcbsize + max_align);
++# endif
+ #elif TLS_DTV_AT_TP
+   tcb_offset = roundup (tcbsize, align ?: 1);
++# ifdef INTERNAL_SYSCALL_NOSYSENTER
++  tlsblock = __sbrk_nosysenter (tcb_offset + memsz + max_align
++                   + TLS_PRE_TCB_SIZE + GL(dl_tls_static_size));
++# else
+   tlsblock = __sbrk (tcb_offset + memsz + max_align
+                    + TLS_PRE_TCB_SIZE + GL(dl_tls_static_size));
++# endif
+   tlsblock += TLS_PRE_TCB_SIZE;
+ #else
+   /* In case a model with a different layout for the TCB and DTV
+--- glibc-2.10.1/misc/sbrk.c
++++ glibc-2.10.1/misc/sbrk.c
+@@ -18,6 +18,7 @@
+ #include <stdint.h>
+ #include <unistd.h>
++#include <sysdep.h>
+ /* Defined in brk.c.  */
+ extern void *__curbrk;
+@@ -29,6 +30,35 @@
+ /* Extend the process's data space by INCREMENT.
+    If INCREMENT is negative, shrink data space by - INCREMENT.
+    Return start of new space allocated, or -1 for errors.  */
++#ifdef INTERNAL_SYSCALL_NOSYSENTER
++/* This version is used by csu/libc-tls.c whem initialising the TLS
++   if the SYSENTER version requires the TLS (which it does on i386).
++   Obviously using the TLS before it is initialised is broken. */
++extern int __brk_nosysenter (void *addr);
++void *
++__sbrk_nosysenter (intptr_t increment)
++{
++  void *oldbrk;
++
++  /* If this is not part of the dynamic library or the library is used
++     via dynamic loading in a statically linked program update
++     __curbrk from the kernel's brk value.  That way two separate
++     instances of __brk and __sbrk can share the heap, returning
++     interleaved pieces of it.  */
++  if (__curbrk == NULL || __libc_multiple_libcs)
++    if (__brk_nosysenter (0) < 0)             /* Initialize the break.  */
++      return (void *) -1;
++
++  if (increment == 0)
++    return __curbrk;
++
++  oldbrk = __curbrk;
++  if (__brk_nosysenter (oldbrk + increment) < 0)
++    return (void *) -1;
++
++  return oldbrk;
++}
++#endif
+ void *
+ __sbrk (intptr_t increment)
+ {
+--- 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 (file)
index 0000000..65693d6
--- /dev/null
@@ -0,0 +1,39 @@
+Change link commands for glibc executables to build PIEs
+
+Patch by Kevin F. Quinn <kevquinn@gentoo.org>
+
+--- 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 (file)
index 0000000..2cb97b9
--- /dev/null
@@ -0,0 +1,243 @@
+Submitted By: Robert Connolly <robert at linuxfromscratch dot org> (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 <unistd.h>
++.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 <unistd.h>
++
++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 <stdio.h>
++
++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 (file)
index 0000000..4d26016
--- /dev/null
@@ -0,0 +1,64 @@
+Submitted By: Robert Connolly <robert at linuxfromscratch dot org> (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 <jakub@redhat.com> 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 (file)
index 0000000..9819b0e
--- /dev/null
@@ -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 <fcntl.h>
+ #endif
+-#if HAVE_SYS_TIME_H || _LIBC
+-# include <sys/time.h>
+-#endif
+-
+ #if HAVE_STDINT_H || _LIBC
+ # include <stdint.h>
+ #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 <hp-timing.h>
+-# 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 (file)
index 0000000..1d69588
--- /dev/null
@@ -0,0 +1,40 @@
+Submitted By: Robert Connolly <robert at linuxfromscratch dot org> (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 (file)
index 0000000..db843f0
--- /dev/null
@@ -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 <unistd.h>
++#include <fcntl.h>
++#include <resolv.h>
++
++#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 <errno.h>
++#endif
++
++#include <stdlib.h>
++#include <string.h>
++#include <sys/time.h>
++#include <sys/times.h>
++
++#ifdef TEST
++#include <stdio.h>
++#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 (file)
index 0000000..1de4c1b
--- /dev/null
@@ -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 (file)
index 0000000..5d0e942
--- /dev/null
@@ -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 <space><tab><newline>. */
+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 (file)
index 0000000..5cbacbf
--- /dev/null
@@ -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 <Todd.Miller@courtesan.com>
++.\"
++.\" 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 <string.h>
++.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 <Todd.Miller@courtesan.com>
++ *
++ * 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 <sys/types.h>
++#include <string.h>
++
++/*
++ * 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 <Todd.Miller@courtesan.com>
++ *
++ * 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 <sys/types.h>
++#include <string.h>
++
++/*
++ * 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 (file)
index 0000000..ce0ebd4
--- /dev/null
@@ -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  <vapier@gentoo.org>
+
+       * 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 <sysdeps/generic/sysdep.h>
+ #ifdef        __ASSEMBLER__
+
+2006-04-25  Mike Frysinger  <vapier@gentoo.org>
+
+       * 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 <sysdep.h>");
++
+ /* The initial common code ends here. */
+ asm ("\n/*@HEADER_ENDS*/");