summaryrefslogtreecommitdiffstats
path: root/package/glibc/2.21/0003-fix-CVE-2014-8121.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/glibc/2.21/0003-fix-CVE-2014-8121.patch')
-rw-r--r--package/glibc/2.21/0003-fix-CVE-2014-8121.patch176
1 files changed, 176 insertions, 0 deletions
diff --git a/package/glibc/2.21/0003-fix-CVE-2014-8121.patch b/package/glibc/2.21/0003-fix-CVE-2014-8121.patch
new file mode 100644
index 0000000000..df3534e879
--- /dev/null
+++ b/package/glibc/2.21/0003-fix-CVE-2014-8121.patch
@@ -0,0 +1,176 @@
+From 6d0b7b443c9735672bb76d003c3f7263c5292d7d Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Wed, 29 Apr 2015 14:41:25 +0200
+Subject: [PATCH 23/27] 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
+
+(cherry picked from commit e871e19b5f19d2e6595e911b0a5b1c19cda20cc7)
+
+Fixes:
+CVE-2014-8121 - Unexpected closing of nss_files databases after lookups
+causes denial of service.
+
+Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
+---
+ 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 d419baf..dc351dd 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 a7a45e5..a7ce5ea 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 0000000..f2e8abc
+--- /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"
+--
+2.6.2
+
OpenPOWER on IntegriCloud