Date: Friday, August 16, 2013 @ 21:23:16 Author: heftig Revision: 95783
archrelease: copy trunk to multilib-testing-x86_64 Added: lib32-glibc/repos/multilib-testing-x86_64/ lib32-glibc/repos/multilib-testing-x86_64/PKGBUILD (from rev 95782, lib32-glibc/trunk/PKGBUILD) lib32-glibc/repos/multilib-testing-x86_64/glibc-2.18-readdir_r-CVE-2013-4237.patch (from rev 95782, lib32-glibc/trunk/glibc-2.18-readdir_r-CVE-2013-4237.patch) lib32-glibc/repos/multilib-testing-x86_64/glibc-2.18-strstr-hackfix.patch (from rev 95782, lib32-glibc/trunk/glibc-2.18-strstr-hackfix.patch) lib32-glibc/repos/multilib-testing-x86_64/lib32-glibc.conf (from rev 95782, lib32-glibc/trunk/lib32-glibc.conf) ------------------------------------------+ PKGBUILD | 136 ++++++++++++++ glibc-2.18-readdir_r-CVE-2013-4237.patch | 281 +++++++++++++++++++++++++++++ glibc-2.18-strstr-hackfix.patch | 13 + lib32-glibc.conf | 1 4 files changed, 431 insertions(+) Copied: lib32-glibc/repos/multilib-testing-x86_64/PKGBUILD (from rev 95782, lib32-glibc/trunk/PKGBUILD) =================================================================== --- multilib-testing-x86_64/PKGBUILD (rev 0) +++ multilib-testing-x86_64/PKGBUILD 2013-08-16 19:23:16 UTC (rev 95783) @@ -0,0 +1,136 @@ +# $Id$ +# Maintainer: Jan Alexander Steffens (heftig) <jan.steff...@gmail.com> +# Contributor: Jan de Groot <j...@archlinux.org> +# Contributor: Allan McRae <al...@archlinux.org> + +# toolchain build order: linux-api-headers->glibc->binutils->gcc->binutils->glibc +# NOTE: valgrind requires rebuilt with each major glibc version + +_pkgbasename=glibc +pkgname=lib32-$_pkgbasename +pkgver=2.18 +pkgrel=2 +pkgdesc="GNU C Library for multilib" +arch=('x86_64') +url="http://www.gnu.org/software/libc" +license=('GPL' 'LGPL') +makedepends=('gcc-multilib>=4.7') +options=('!strip' '!emptydirs') +source=(http://ftp.gnu.org/gnu/libc/${_pkgbasename}-${pkgver}.tar.xz{,.sig} + glibc-2.18-readdir_r-CVE-2013-4237.patch + glibc-2.18-strstr-hackfix.patch + lib32-glibc.conf) +md5sums=('88fbbceafee809e82efd52efa1e3c58f' + 'SKIP' + '154da6bf5a5248f42a7bf5bf08e01a47' + '4441f6dfe7d75ced1fa75e54dd21d36e' + '6e052f1cb693d5d3203f50f9d4e8c33b') + + +prepare() { + cd ${srcdir}/${_pkgbasename}-${pkgver} + + # upstream commit 91ce4085 + patch -p1 -i $srcdir/glibc-2.18-readdir_r-CVE-2013-4237.patch + + # hack fix for strstr issues on x86 + patch -p1 -i $srcdir/glibc-2.18-strstr-hackfix.patch + + mkdir ${srcdir}/glibc-build +} + +build() { + cd ${srcdir}/glibc-build + + #if [[ ${CARCH} = "i686" ]]; then + # Hack to fix NPTL issues with Xen, only required on 32bit platforms + # TODO: make separate glibc-xen package for i686 + export CFLAGS="${CFLAGS} -mno-tls-direct-seg-refs" + #fi + + echo "slibdir=/usr/lib32" >> configparms + echo "sbindir=/usr/bin" >> configparms + echo "rootsbindir=/usr/bin" >> configparms + + export CC="gcc -m32" + export CXX="g++ -m32" + + # remove hardening options for building libraries + CFLAGS=${CFLAGS/-fstack-protector/} + CPPFLAGS=${CPPFLAGS/-D_FORTIFY_SOURCE=2/} + + ${srcdir}/${_pkgbasename}-${pkgver}/configure --prefix=/usr \ + --libdir=/usr/lib32 --libexecdir=/usr/lib32 \ + --with-headers=/usr/include \ + --with-bugurl=https://bugs.archlinux.org/ \ + --enable-add-ons=nptl,libidn \ + --enable-obsolete-rpc \ + --enable-kernel=2.6.32 \ + --enable-bind-now --disable-profile \ + --enable-stackguard-randomization \ + --enable-multi-arch i686-unknown-linux-gnu + + # build libraries with hardening disabled + echo "build-programs=no" >> configparms + make + + # re-enable hardening for programs + sed -i "/build-programs=/s#no#yes#" configparms + echo "CC += -fstack-protector -D_FORTIFY_SOURCE=2" >> configparms + echo "CXX += -fstack-protector -D_FORTIFY_SOURCE=2" >> configparms + make + + # remove harding in preparation to run test-suite + sed -i '4,6d' configparms +} + +check() { + # bug to file - the linker commands need to be reordered + LDFLAGS=${LDFLAGS/--as-needed,/} + + cd ${srcdir}/glibc-build + make check +} + +package() { + cd ${srcdir}/glibc-build + make install_root=${pkgdir} install + + rm -rf ${pkgdir}/{etc,sbin,usr/{bin,sbin,share},var} + + # We need one 32 bit specific header file + find ${pkgdir}/usr/include -type f -not -name stubs-32.h -delete + + + # Dynamic linker + mkdir ${pkgdir}/usr/lib + ln -s ../lib32/ld-linux.so.2 ${pkgdir}/usr/lib/ + + # Add lib32 paths to the default library search path + install -Dm644 "$srcdir/lib32-glibc.conf" "$pkgdir/etc/ld.so.conf.d/lib32-glibc.conf" + + # Symlink /usr/lib32/locale to /usr/lib/locale + ln -s ../lib/locale "$pkgdir/usr/lib32/locale" + + # Do not strip the following files for improved debugging support + # ("improved" as in not breaking gdb and valgrind...): + # ld-${pkgver}.so + # libc-${pkgver}.so + # libpthread-${pkgver}.so + # libthread_db-1.0.so + + cd $pkgdir + strip $STRIP_BINARIES \ + \ + \ + usr/lib32/getconf/* + + + strip $STRIP_STATIC usr/lib32/*.a + + strip $STRIP_SHARED usr/lib32/{libanl,libBrokenLocale,libcidn,libcrypt}-*.so \ + usr/lib32/libnss_{compat,db,dns,files,hesiod,nis,nisplus}-*.so \ + usr/lib32/{libdl,libm,libnsl,libresolv,librt,libutil}-*.so \ + usr/lib32/{libmemusage,libpcprofile,libSegFault}.so \ + usr/lib32/{audit,gconv}/*.so +} Copied: lib32-glibc/repos/multilib-testing-x86_64/glibc-2.18-readdir_r-CVE-2013-4237.patch (from rev 95782, lib32-glibc/trunk/glibc-2.18-readdir_r-CVE-2013-4237.patch) =================================================================== --- multilib-testing-x86_64/glibc-2.18-readdir_r-CVE-2013-4237.patch (rev 0) +++ multilib-testing-x86_64/glibc-2.18-readdir_r-CVE-2013-4237.patch 2013-08-16 19:23:16 UTC (rev 95783) @@ -0,0 +1,281 @@ +diff --git a/manual/conf.texi b/manual/conf.texi +index 7eb8b36..c720063 100644 +--- a/manual/conf.texi ++++ b/manual/conf.texi +@@ -1149,6 +1149,9 @@ typed ahead as input. @xref{I/O Queues}. + @deftypevr Macro int NAME_MAX + The uniform system limit (if any) for the length of a file name component, not + including the terminating null character. ++ ++@strong{Portability Note:} On some systems, @theglibc{} defines ++@code{NAME_MAX}, but does not actually enforce this limit. + @end deftypevr + + @comment limits.h +@@ -1157,6 +1160,9 @@ including the terminating null character. + The uniform system limit (if any) for the length of an entire file name (that + is, the argument given to system calls such as @code{open}), including the + terminating null character. ++ ++@strong{Portability Note:} @Theglibc{} does not enforce this limit ++even if @code{PATH_MAX} is defined. + @end deftypevr + + @cindex limits, pipe buffer size +@@ -1476,6 +1482,9 @@ Inquire about the value of @code{POSIX_REC_MIN_XFER_SIZE}. + Inquire about the value of @code{POSIX_REC_XFER_ALIGN}. + @end table + ++@strong{Portability Note:} On some systems, @theglibc{} does not ++enforce @code{_PC_NAME_MAX} or @code{_PC_PATH_MAX} limits. ++ + @node Utility Limits + @section Utility Program Capacity Limits + +diff --git a/manual/filesys.texi b/manual/filesys.texi +index 1df9cf2..814c210 100644 +--- a/manual/filesys.texi ++++ b/manual/filesys.texi +@@ -444,9 +444,9 @@ symbols are declared in the header file @file{dirent.h}. + @comment POSIX.1 + @deftypefun {struct dirent *} readdir (DIR *@var{dirstream}) + This function reads the next entry from the directory. It normally +-returns a pointer to a structure containing information about the file. +-This structure is statically allocated and can be rewritten by a +-subsequent call. ++returns a pointer to a structure containing information about the ++file. This structure is associated with the @var{dirstream} handle ++and can be rewritten by a subsequent call. + + @strong{Portability Note:} On some systems @code{readdir} may not + return entries for @file{.} and @file{..}, even though these are always +@@ -461,19 +461,61 @@ conditions are defined for this function: + The @var{dirstream} argument is not valid. + @end table + +-@code{readdir} is not thread safe. Multiple threads using +-@code{readdir} on the same @var{dirstream} may overwrite the return +-value. Use @code{readdir_r} when this is critical. ++To distinguish between an end-of-directory condition or an error, you ++must set @code{errno} to zero before calling @code{readdir}. To avoid ++entering an infinite loop, you should stop reading from the directory ++after the first error. ++ ++In POSIX.1-2008, @code{readdir} is not thread-safe. In @theglibc{} ++implementation, it is safe to call @code{readdir} concurrently on ++different @var{dirstream}s, but multiple threads accessing the same ++@var{dirstream} result in undefined behavior. @code{readdir_r} is a ++fully thread-safe alternative, but suffers from poor portability (see ++below). It is recommended that you use @code{readdir}, with external ++locking if multiple threads access the same @var{dirstream}. + @end deftypefun + + @comment dirent.h + @comment GNU + @deftypefun int readdir_r (DIR *@var{dirstream}, struct dirent *@var{entry}, struct dirent **@var{result}) +-This function is the reentrant version of @code{readdir}. Like +-@code{readdir} it returns the next entry from the directory. But to +-prevent conflicts between simultaneously running threads the result is +-not stored in statically allocated memory. Instead the argument +-@var{entry} points to a place to store the result. ++This function is a version of @code{readdir} which performs internal ++locking. Like @code{readdir} it returns the next entry from the ++directory. To prevent conflicts between simultaneously running ++threads the result is stored inside the @var{entry} object. ++ ++@strong{Portability Note:} It is recommended to use @code{readdir} ++instead of @code{readdir_r} for the following reasons: ++ ++@itemize @bullet ++@item ++On systems which do not define @code{NAME_MAX}, it may not be possible ++to use @code{readdir_r} safely because the caller does not specify the ++length of the buffer for the directory entry. ++ ++@item ++On some systems, @code{readdir_r} cannot read directory entries with ++very long names. If such a name is encountered, @theglibc{} ++implementation of @code{readdir_r} returns with an error code of ++@code{ENAMETOOLONG} after the final directory entry has been read. On ++other systems, @code{readdir_r} may return successfully, but the ++@code{d_name} member may not be NUL-terminated or may be truncated. ++ ++@item ++POSIX-1.2008 does not guarantee that @code{readdir} is thread-safe, ++even when access to the same @var{dirstream} is serialized. But in ++current implementations (including @theglibc{}), it is safe to call ++@code{readdir} concurrently on different @var{dirstream}s, so there is ++no need to use @code{readdir_r} in most multi-threaded programs. In ++the rare case that multiple threads need to read from the same ++@var{dirstream}, it is still better to use @code{readdir} and external ++synchronization. ++ ++@item ++It is expected that future versions of POSIX will obsolete ++@code{readdir_r} and mandate the level of thread safety for ++@code{readdir} which is provided by @theglibc{} and other ++implementations today. ++@end itemize + + Normally @code{readdir_r} returns zero and sets @code{*@var{result}} + to @var{entry}. If there are no more entries in the directory or an +@@ -481,15 +523,6 @@ error is detected, @code{readdir_r} sets @code{*@var{result}} to a + null pointer and returns a nonzero error code, also stored in + @code{errno}, as described for @code{readdir}. + +-@strong{Portability Note:} On some systems @code{readdir_r} may not +-return a NUL terminated string for the file name, even when there is no +-@code{d_reclen} field in @code{struct dirent} and the file +-name is the maximum allowed size. Modern systems all have the +-@code{d_reclen} field, and on old systems multi-threading is not +-critical. In any case there is no such problem with the @code{readdir} +-function, so that even on systems without the @code{d_reclen} member one +-could use multiple threads by using external locking. +- + It is also important to look at the definition of the @code{struct + dirent} type. Simply passing a pointer to an object of this type for + the second parameter of @code{readdir_r} might not be enough. Some +diff --git a/sysdeps/posix/dirstream.h b/sysdeps/posix/dirstream.h +index a7a074d..8e8570d 100644 +--- a/sysdeps/posix/dirstream.h ++++ b/sysdeps/posix/dirstream.h +@@ -39,6 +39,8 @@ struct __dirstream + + off_t filepos; /* Position of next entry to read. */ + ++ int errcode; /* Delayed error code. */ ++ + /* Directory block. */ + char data[0] __attribute__ ((aligned (__alignof__ (void*)))); + }; +diff --git a/sysdeps/posix/opendir.c b/sysdeps/posix/opendir.c +index ddfc3a7..fc05b0f 100644 +--- a/sysdeps/posix/opendir.c ++++ b/sysdeps/posix/opendir.c +@@ -231,6 +231,7 @@ __alloc_dir (int fd, bool close_fd, int flags, const struct stat64 *statp) + dirp->size = 0; + dirp->offset = 0; + dirp->filepos = 0; ++ dirp->errcode = 0; + + return dirp; + } +diff --git a/sysdeps/posix/readdir_r.c b/sysdeps/posix/readdir_r.c +index b5a8e2e..8ed5c3f 100644 +--- a/sysdeps/posix/readdir_r.c ++++ b/sysdeps/posix/readdir_r.c +@@ -40,6 +40,7 @@ __READDIR_R (DIR *dirp, DIRENT_TYPE *entry, DIRENT_TYPE **result) + DIRENT_TYPE *dp; + size_t reclen; + const int saved_errno = errno; ++ int ret; + + __libc_lock_lock (dirp->lock); + +@@ -70,10 +71,10 @@ __READDIR_R (DIR *dirp, DIRENT_TYPE *entry, DIRENT_TYPE **result) + bytes = 0; + __set_errno (saved_errno); + } ++ if (bytes < 0) ++ dirp->errcode = errno; + + dp = NULL; +- /* Reclen != 0 signals that an error occurred. */ +- reclen = bytes != 0; + break; + } + dirp->size = (size_t) bytes; +@@ -106,29 +107,46 @@ __READDIR_R (DIR *dirp, DIRENT_TYPE *entry, DIRENT_TYPE **result) + dirp->filepos += reclen; + #endif + +- /* Skip deleted files. */ ++#ifdef NAME_MAX ++ if (reclen > offsetof (DIRENT_TYPE, d_name) + NAME_MAX + 1) ++ { ++ /* The record is very long. It could still fit into the ++ caller-supplied buffer if we can skip padding at the ++ end. */ ++ size_t namelen = _D_EXACT_NAMLEN (dp); ++ if (namelen <= NAME_MAX) ++ reclen = offsetof (DIRENT_TYPE, d_name) + namelen + 1; ++ else ++ { ++ /* The name is too long. Ignore this file. */ ++ dirp->errcode = ENAMETOOLONG; ++ dp->d_ino = 0; ++ continue; ++ } ++ } ++#endif ++ ++ /* Skip deleted and ignored files. */ + } + while (dp->d_ino == 0); + + if (dp != NULL) + { +-#ifdef GETDENTS_64BIT_ALIGNED +- /* The d_reclen value might include padding which is not part of +- the DIRENT_TYPE data structure. */ +- reclen = MIN (reclen, +- offsetof (DIRENT_TYPE, d_name) + sizeof (dp->d_name)); +-#endif + *result = memcpy (entry, dp, reclen); +-#ifdef GETDENTS_64BIT_ALIGNED ++#ifdef _DIRENT_HAVE_D_RECLEN + entry->d_reclen = reclen; + #endif ++ ret = 0; + } + else +- *result = NULL; ++ { ++ *result = NULL; ++ ret = dirp->errcode; ++ } + + __libc_lock_unlock (dirp->lock); + +- return dp != NULL ? 0 : reclen ? errno : 0; ++ return ret; + } + + #ifdef __READDIR_R_ALIAS +diff --git a/sysdeps/posix/rewinddir.c b/sysdeps/posix/rewinddir.c +index 2935a8e..d4991ad 100644 +--- a/sysdeps/posix/rewinddir.c ++++ b/sysdeps/posix/rewinddir.c +@@ -33,6 +33,7 @@ rewinddir (dirp) + dirp->filepos = 0; + dirp->offset = 0; + dirp->size = 0; ++ dirp->errcode = 0; + #ifndef NOT_IN_libc + __libc_lock_unlock (dirp->lock); + #endif +diff --git a/sysdeps/unix/sysv/linux/i386/readdir64_r.c b/sysdeps/unix/sysv/linux/i386/readdir64_r.c +index 8ebbcfd..a7d114e 100644 +--- a/sysdeps/unix/sysv/linux/i386/readdir64_r.c ++++ b/sysdeps/unix/sysv/linux/i386/readdir64_r.c +@@ -18,7 +18,6 @@ + #define __READDIR_R __readdir64_r + #define __GETDENTS __getdents64 + #define DIRENT_TYPE struct dirent64 +-#define GETDENTS_64BIT_ALIGNED 1 + + #include <sysdeps/posix/readdir_r.c> + +diff --git a/sysdeps/unix/sysv/linux/wordsize-64/readdir_r.c b/sysdeps/unix/sysv/linux/wordsize-64/readdir_r.c +index 5ed8e95..290f2c8 100644 +--- a/sysdeps/unix/sysv/linux/wordsize-64/readdir_r.c ++++ b/sysdeps/unix/sysv/linux/wordsize-64/readdir_r.c +@@ -1,5 +1,4 @@ + #define readdir64_r __no_readdir64_r_decl +-#define GETDENTS_64BIT_ALIGNED 1 + #include <sysdeps/posix/readdir_r.c> + #undef readdir64_r + weak_alias (__readdir_r, readdir64_r) +-- +1.8.3.4 + Copied: lib32-glibc/repos/multilib-testing-x86_64/glibc-2.18-strstr-hackfix.patch (from rev 95782, lib32-glibc/trunk/glibc-2.18-strstr-hackfix.patch) =================================================================== --- multilib-testing-x86_64/glibc-2.18-strstr-hackfix.patch (rev 0) +++ multilib-testing-x86_64/glibc-2.18-strstr-hackfix.patch 2013-08-16 19:23:16 UTC (rev 95783) @@ -0,0 +1,13 @@ +diff --git a/sysdeps/x86_64/multiarch/strstr.c b/sysdeps/x86_64/multiarch/strstr.c +index cd63b68..03d8b9a 100644 +--- a/sysdeps/x86_64/multiarch/strstr.c ++++ b/sysdeps/x86_64/multiarch/strstr.c +@@ -86,7 +86,7 @@ + /* Simple replacement of movdqu to address 4KB boundary cross issue. + If EOS occurs within less than 16B before 4KB boundary, we don't + cross to next page. */ +-static __m128i ++static inline __m128i + __m128i_strloadu (const unsigned char * p, __m128i zero) + { + if (__builtin_expect ((int) ((size_t) p & 0xfff) > 0xff0, 0)) Copied: lib32-glibc/repos/multilib-testing-x86_64/lib32-glibc.conf (from rev 95782, lib32-glibc/trunk/lib32-glibc.conf) =================================================================== --- multilib-testing-x86_64/lib32-glibc.conf (rev 0) +++ multilib-testing-x86_64/lib32-glibc.conf 2013-08-16 19:23:16 UTC (rev 95783) @@ -0,0 +1 @@ +/usr/lib32