diff options
author | Stan Shebs <stanshebs@google.com> | 2015-09-16 10:29:39 -0700 |
---|---|---|
committer | Stan Shebs <stanshebs@google.com> | 2015-09-16 10:29:39 -0700 |
commit | 107aed9f2ba617c6807f836a12a127ec2177c650 (patch) | |
tree | b015415e91eb6720eec9358b4aa607089a65781a | |
parent | b1342139cd437bcae24e1bc3d473d31e2779b517 (diff) | |
download | glibc-107aed9f2ba617c6807f836a12a127ec2177c650.zip glibc-107aed9f2ba617c6807f836a12a127ec2177c650.tar.gz glibc-107aed9f2ba617c6807f836a12a127ec2177c650.tar.bz2 |
Backport upstream fix to nss_files
-rw-r--r-- | README.google | 7 | ||||
-rw-r--r-- | nss/Makefile | 2 | ||||
-rw-r--r-- | nss/nss_files/files-XXX.c | 2 | ||||
-rw-r--r-- | nss/tst-nss-getpwent.c | 118 |
4 files changed, 127 insertions, 2 deletions
diff --git a/README.google b/README.google index 6a1daad..b7a1f92 100644 --- a/README.google +++ b/README.google @@ -487,3 +487,10 @@ posix/tst-fnmatch3.c https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=4a28f4d55a6cc33474c0792fe93b5942d81bf185 https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=c2c6d39fab901c97c18fa3a3a3658d9dc3f7df61 (stanshebs, backport) + +nss/nss_files/files-XXX.c +nss/Makefile +nss/tst-nss-getpwent.c + For b/19498319, backport fix for nss_files file management (PR18007, CVE-2014-8121) + https://sourceware.org/git/?p=glibc.git;a=commit;h=03d2730b44cc2236318fd978afa2651753666c55 + (stanshebs, backport) diff --git a/nss/Makefile b/nss/Makefile index 69b1f80..6bd3a22 100644 --- a/nss/Makefile +++ b/nss/Makefile @@ -38,7 +38,7 @@ install-bin := getent 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 include ../Makeconfig diff --git a/nss/nss_files/files-XXX.c b/nss/nss_files/files-XXX.c index 36242f9..733ae69 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" |