summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Olbrich <m.olbrich@pengutronix.de>2015-07-06 10:04:07 +0200
committerMichael Olbrich <m.olbrich@pengutronix.de>2015-07-06 10:04:07 +0200
commit72dd7f1877da221bbe328731b65851cb5f56ec4b (patch)
treed9d558d9554c1442316dcdf14f36e12fb2a1fc91
parent61da94e6331800a0dc42a6a1bc996cc33ab290b2 (diff)
downloadOSELAS.Toolchain-72dd7f1877da221bbe328731b65851cb5f56ec4b.tar.gz
glibc: add more security fixes
Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
-rw-r--r--patches/glibc-2.20/0005-CVE-2014-8121-Do-not-close-NSS-files-database-during.patch226
-rw-r--r--patches/glibc-2.20/0006-CVE-2015-1781-resolv-nss_dns-dns-host.c-buffer-overf.patch23
-rw-r--r--patches/glibc-2.20/series4
3 files changed, 252 insertions, 1 deletions
diff --git a/patches/glibc-2.20/0005-CVE-2014-8121-Do-not-close-NSS-files-database-during.patch b/patches/glibc-2.20/0005-CVE-2014-8121-Do-not-close-NSS-files-database-during.patch
new file mode 100644
index 0000000..17861f7
--- /dev/null
+++ b/patches/glibc-2.20/0005-CVE-2014-8121-Do-not-close-NSS-files-database-during.patch
@@ -0,0 +1,226 @@
+From: Florian Weimer <fweimer@redhat.com>
+Date: Wed, 29 Apr 2015 14:41:25 +0200
+Subject: [PATCH] CVE-2014-8121: Do not close NSS files database during
+ iteration [BZ #18007]
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Robin Hack discovered Samba would enter an infinite loop processing
+certain quota-related requests. We eventually tracked this down to a
+glibc issue.
+
+Running a (simplified) test case under strace shows that /etc/passwd
+is continuously opened and closed:
+
+…
+open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 3
+lseek(3, 0, SEEK_CUR) = 0
+read(3, "root:x:0:0:root:/root:/bin/bash\n"..., 4096) = 2717
+lseek(3, 2717, SEEK_SET) = 2717
+close(3) = 0
+open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 3
+lseek(3, 0, SEEK_CUR) = 0
+lseek(3, 0, SEEK_SET) = 0
+read(3, "root:x:0:0:root:/root:/bin/bash\n"..., 4096) = 2717
+lseek(3, 2717, SEEK_SET) = 2717
+close(3) = 0
+open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 3
+lseek(3, 0, SEEK_CUR) = 0
+…
+
+The lookup function implementation in
+nss/nss_files/files-XXX.c:DB_LOOKUP has code to prevent that. It is
+supposed skip closing the input file if it was already open.
+
+ /* Reset file pointer to beginning or open file. */ \
+ status = internal_setent (keep_stream); \
+ \
+ if (status == NSS_STATUS_SUCCESS) \
+ { \
+ /* Tell getent function that we have repositioned the file pointer. */ \
+ last_use = getby; \
+ \
+ while ((status = internal_getent (result, buffer, buflen, errnop \
+ H_ERRNO_ARG EXTRA_ARGS_VALUE)) \
+ == NSS_STATUS_SUCCESS) \
+ { break_if_match } \
+ \
+ if (! keep_stream) \
+ internal_endent (); \
+ } \
+
+keep_stream is initialized from the stayopen flag in internal_setent.
+internal_setent is called from the set*ent implementation as:
+
+ status = internal_setent (stayopen);
+
+However, for non-host database, this flag is always 0, per the
+STAYOPEN magic in nss/getXXent_r.c.
+
+Thus, the fix is this:
+
+- status = internal_setent (stayopen);
++ status = internal_setent (1);
+
+This is not a behavioral change even for the hosts database (where the
+application can specify the stayopen flag) because with a call to
+sethostent(0), the file handle is still not closed in the
+implementation of gethostent.
+---
+ nss/Makefile | 2 +-
+ nss/nss_files/files-XXX.c | 2 +-
+ nss/tst-nss-getpwent.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 120 insertions(+), 2 deletions(-)
+ create mode 100644 nss/tst-nss-getpwent.c
+
+diff --git a/nss/Makefile b/nss/Makefile
+index 1fa7f1f397f5..d6f0139bf5c8 100644
+--- a/nss/Makefile
++++ b/nss/Makefile
+@@ -39,7 +39,7 @@ install-bin := getent makedb
+ makedb-modules = xmalloc hash-string
+ extra-objs += $(makedb-modules:=.o)
+
+-tests = test-netdb tst-nss-test1 test-digits-dots
++tests = test-netdb tst-nss-test1 test-digits-dots tst-nss-getpwent
+ xtests = bug-erange
+
+ # Specify rules for the nss_* modules. We have some services.
+diff --git a/nss/nss_files/files-XXX.c b/nss/nss_files/files-XXX.c
+index 212b938fdf39..cc38174df0c2 100644
+--- a/nss/nss_files/files-XXX.c
++++ b/nss/nss_files/files-XXX.c
+@@ -134,7 +134,7 @@ CONCAT(_nss_files_set,ENTNAME) (int stayopen)
+
+ __libc_lock_lock (lock);
+
+- status = internal_setent (stayopen);
++ status = internal_setent (1);
+
+ if (status == NSS_STATUS_SUCCESS && fgetpos (stream, &position) < 0)
+ {
+diff --git a/nss/tst-nss-getpwent.c b/nss/tst-nss-getpwent.c
+new file mode 100644
+index 000000000000..f2e8abce6098
+--- /dev/null
++++ b/nss/tst-nss-getpwent.c
+@@ -0,0 +1,118 @@
++/* Copyright (C) 2015 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <http://www.gnu.org/licenses/>. */
++
++#include <pwd.h>
++#include <stdbool.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++
++int
++do_test (void)
++{
++ /* Count the number of entries in the password database, and fetch
++ data from the first and last entries. */
++ size_t count = 0;
++ struct passwd * pw;
++ char *first_name = NULL;
++ uid_t first_uid = 0;
++ char *last_name = NULL;
++ uid_t last_uid = 0;
++ setpwent ();
++ while ((pw = getpwent ()) != NULL)
++ {
++ if (first_name == NULL)
++ {
++ first_name = strdup (pw->pw_name);
++ if (first_name == NULL)
++ {
++ printf ("strdup: %m\n");
++ return 1;
++ }
++ first_uid = pw->pw_uid;
++ }
++
++ free (last_name);
++ last_name = strdup (pw->pw_name);
++ if (last_name == NULL)
++ {
++ printf ("strdup: %m\n");
++ return 1;
++ }
++ last_uid = pw->pw_uid;
++ ++count;
++ }
++ endpwent ();
++
++ if (count == 0)
++ {
++ printf ("No entries in the password database.\n");
++ return 0;
++ }
++
++ /* Try again, this time interleaving with name-based and UID-based
++ lookup operations. The counts do not match if the interleaved
++ lookups affected the enumeration. */
++ size_t new_count = 0;
++ setpwent ();
++ while ((pw = getpwent ()) != NULL)
++ {
++ if (new_count == count)
++ {
++ printf ("Additional entry in the password database.\n");
++ return 1;
++ }
++ ++new_count;
++ struct passwd *pw2 = getpwnam (first_name);
++ if (pw2 == NULL)
++ {
++ printf ("getpwnam (%s) failed: %m\n", first_name);
++ return 1;
++ }
++ pw2 = getpwnam (last_name);
++ if (pw2 == NULL)
++ {
++ printf ("getpwnam (%s) failed: %m\n", last_name);
++ return 1;
++ }
++ pw2 = getpwuid (first_uid);
++ if (pw2 == NULL)
++ {
++ printf ("getpwuid (%llu) failed: %m\n",
++ (unsigned long long) first_uid);
++ return 1;
++ }
++ pw2 = getpwuid (last_uid);
++ if (pw2 == NULL)
++ {
++ printf ("getpwuid (%llu) failed: %m\n",
++ (unsigned long long) last_uid);
++ return 1;
++ }
++ }
++ endpwent ();
++ if (new_count < count)
++ {
++ printf ("Missing entry in the password database.\n");
++ return 1;
++ }
++
++ return 0;
++}
++
++#define TEST_FUNCTION do_test ()
++#include "../test-skeleton.c"
diff --git a/patches/glibc-2.20/0006-CVE-2015-1781-resolv-nss_dns-dns-host.c-buffer-overf.patch b/patches/glibc-2.20/0006-CVE-2015-1781-resolv-nss_dns-dns-host.c-buffer-overf.patch
new file mode 100644
index 0000000..3c035a4
--- /dev/null
+++ b/patches/glibc-2.20/0006-CVE-2015-1781-resolv-nss_dns-dns-host.c-buffer-overf.patch
@@ -0,0 +1,23 @@
+From: Arjun Shankar <arjun.is@lostca.se>
+Date: Tue, 21 Apr 2015 14:06:31 +0200
+Subject: [PATCH] CVE-2015-1781: resolv/nss_dns/dns-host.c buffer overflow
+ [BZ#18287]
+
+---
+ resolv/nss_dns/dns-host.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
+index 3258e709d20c..ed997030331c 100644
+--- a/resolv/nss_dns/dns-host.c
++++ b/resolv/nss_dns/dns-host.c
+@@ -615,7 +615,8 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
+ int have_to_map = 0;
+ uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data);
+ buffer += pad;
+- if (__glibc_unlikely (buflen < sizeof (struct host_data) + pad))
++ buflen = buflen > pad ? buflen - pad : 0;
++ if (__glibc_unlikely (buflen < sizeof (struct host_data)))
+ {
+ /* The buffer is too small. */
+ too_small:
diff --git a/patches/glibc-2.20/series b/patches/glibc-2.20/series
index 04144e3..992d079 100644
--- a/patches/glibc-2.20/series
+++ b/patches/glibc-2.20/series
@@ -5,6 +5,8 @@
0002-CVE-2012-3406-Stack-overflow-in-vfprintf-BZ-16617.patch
0003-CVE-2014-7817-wordexp-fails-to-honour-WRDE_NOCMD.patch
0004-CVE-2015-1472-wscanf-allocates-too-little-memory.patch
+0005-CVE-2014-8121-Do-not-close-NSS-files-database-during.patch
+0006-CVE-2015-1781-resolv-nss_dns-dns-host.c-buffer-overf.patch
#tag:build-system --start-number 100
0100-add-install-lib-all-target.patch
0101-don-t-regen-docs-if-perl-is-not-found.patch
@@ -19,4 +21,4 @@
0500-Hack-around-mips-args-to-host-gcc.patch
#tag:open-glibc-bugs --start-number 600
0600-ARM-fix-PI-futex-breakge-glibc-bug-18463.patch
-# 3558b892a89c6287a934fa9cf65be74d - git-ptx-patches magic
+# 9b9561d3bd8d2a555c8bae5ece64e366 - git-ptx-patches magic