[nss_db] - import patch to handle initgroups directly rather than forcing libc to use the enumeration interfa
Nalin Dahyabhai
nalin at fedoraproject.org
Wed May 18 18:06:40 UTC 2011
commit 65a7a67a7c0bc53d9cee78dd4f7c501b5387b76c
Author: Nalin Dahyabhai <nalin at redhat.com>
Date: Wed May 18 14:06:00 2011 -0400
- import patch to handle initgroups directly rather than forcing libc to use the enumeration interfaces, which could result in two threads calling initgroups() at the same time to both get a subset of the right answers (#705466)
d-nss_db-initgr.patch | 254 +++++++++++++++++++++++++++++++++++++++++++++++++
nss_db.spec | 10 ++-
2 files changed, 263 insertions(+), 1 deletions(-)
---
diff --git a/d-nss_db-initgr.patch b/d-nss_db-initgr.patch
new file mode 100644
index 0000000..d70c9c7
--- /dev/null
+++ b/d-nss_db-initgr.patch
@@ -0,0 +1,254 @@
+diff -up ./src/db-initgroups.c.initgr ./src/db-initgroups.c
+--- a/src/db-initgroups.c.initgr 2011-04-21 13:37:34.913687000 -0400
++++ b/src/db-initgroups.c 2011-04-21 14:13:11.826667000 -0400
+@@ -0,0 +1,192 @@
++/* Initgroups handling in nss_db module.
++ Copyright (C) 2011 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 Library General Public License as
++ published by the Free Software Foundation; either version 2 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
++ Library General Public License for more details.
++
++ You should have received a copy of the GNU Library General Public
++ License along with the GNU C Library; see the file COPYING.LIB. If not,
++ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ Boston, MA 02111-1307, USA. */
++
++#include <alloca.h>
++#include <ctype.h>
++#include <errno.h>
++#include <grp.h>
++#include <paths.h>
++#include <stdbool.h>
++#include <stdlib.h>
++#include <string.h>
++#include <sys/param.h>
++
++#include "nss_db.h"
++
++/* Declared in glibc's include/grp.h. */
++extern int _nss_files_parse_grent (char *line, struct group *result,
++ void *data, size_t datalen, int *errnop);
++
++
++enum nss_status
++_nss_db_initgroups_dyn (const char *user, gid_t group, long int *start,
++ long int *size, gid_t **groupsp, long int limit,
++ int *errnop)
++{
++ DB *db = NULL;
++ DB_ENV *dbenv = NULL;
++
++ /* Open the database. */
++ enum nss_status status = internal_setent (_PATH_VARDB "group.db", &db,
++ &dbenv);
++ if (status == NSS_STATUS_SUCCESS)
++ {
++ unsigned int entidx = 0;
++
++ size_t linelen = 1024;
++ void *line = alloca (linelen);
++ bool line_use_malloc = false;
++
++ size_t buflen = 1024;
++ void *buffer = alloca (buflen);
++ bool buffer_use_malloc = false;
++
++ size_t alloca_used = linelen + buflen;
++
++ gid_t *groups = *groupsp;
++
++ while (1)
++ {
++ char buf[20];
++ DBT key;
++
++ key.size = snprintf (key.data = buf, sizeof buf, "0%u", entidx++);
++ key.flags = 0;
++
++ DBT value;
++ value.flags = 0;
++ int err = db->get (db, NULL, &key, &value, 0);
++ if (err)
++ {
++ if (err != DB_NOTFOUND)
++ {
++ if (err > 0)
++ *errnop = err;
++ status = NSS_STATUS_UNAVAIL;
++ }
++ break;
++ }
++
++ /* We need a copy of the value we can modify. */
++ if (linelen < value.size)
++ {
++ size_t newlinelen = MAX (2 * linelen, value.size);
++
++ if (line_use_malloc
++ || ! __libc_use_alloca (alloca_used + newlinelen))
++ {
++ void *newline = realloc (line_use_malloc ? line : NULL,
++ newlinelen);
++ if (newline == NULL)
++ {
++ *errnop = ENOMEM;
++ status = NSS_STATUS_TRYAGAIN;
++ goto out;
++ }
++ line = newline;
++ linelen = newlinelen;
++ line_use_malloc = true;
++ }
++ else
++ {
++ line = extend_alloca (line, linelen, newlinelen);
++ alloca_used += newlinelen;
++ }
++ }
++
++ /* Copy and find beginning. */
++ char *p = memcpy (line, value.data, value.size);
++ while (isspace (*p))
++ ++p;
++
++ struct group grp;
++ while ((err = _nss_files_parse_grent (p, &grp, buffer, buflen,
++ errnop)) == -1)
++ {
++ size_t newbuflen = MAX (2 * buflen, value.size);
++ if (buffer_use_malloc
++ || ! __libc_use_alloca (alloca_used + newbuflen))
++ {
++ void *newbuf = realloc (buffer_use_malloc ? buffer : NULL,
++ newbuflen);
++ if (newbuf == NULL)
++ {
++ *errnop = ENOMEM;
++ status = NSS_STATUS_TRYAGAIN;
++ goto out;
++ }
++ buffer = newbuf;
++ buflen = newbuflen;
++ buffer_use_malloc = true;
++ }
++ else
++ {
++ buffer = extend_alloca (buffer, buflen, newbuflen);
++ alloca_used += newbuflen;
++ }
++ }
++
++ if (err > 0 && grp.gr_gid != group)
++ for (char **m = grp.gr_mem; *m != NULL; ++m)
++ if (strcmp (*m, user) == 0)
++ {
++ /* Matches user. Insert this group. */
++ if (*start == *size)
++ {
++ /* Need a bigger buffer. */
++ if (limit > 0 && *size == limit)
++ /* We reached the maximum. */
++ goto out;
++
++ long int newsize;
++ if (limit <= 0)
++ newsize = 2 * *size;
++ else
++ newsize = MIN (limit, 2 * *size);
++
++ gid_t *newgroups = realloc (groups,
++ newsize * sizeof (*groups));
++ if (newgroups == NULL)
++ {
++ *errnop = ENOMEM;
++ status = NSS_STATUS_TRYAGAIN;
++ goto out;
++ }
++ *groupsp = groups = newgroups;
++ *size = newsize;
++ }
++
++ groups[*start] = grp.gr_gid;
++ *start += 1;
++
++ break;
++ }
++ }
++
++ out:
++ if (buffer_use_malloc)
++ free (buffer);
++ if (line_use_malloc)
++ free (line);
++
++ internal_endent (&db, &dbenv);
++ }
++
++ return status;
++}
+--- a/src/Makefile.am.initgr 2011-04-21 13:43:11.698540000 -0400
++++ b/src/Makefile.am 2011-04-21 14:12:27.750429000 -0400
+@@ -11,14 +11,15 @@ localedir = $(datadir)/locale
+
+ noinst_HEADERS = db-compat.h netgroup.h nss_db.h
+
+-INCLUDES = @DB_CFLAGS@ -D_GNU_SOURCE \
++INCLUDES = @DB_CFLAGS@ -D_GNU_SOURCE -std=gnu99 \
+ -I../intl -DLOCALEDIR=\"$(localedir)\"
+
+ EXTRA_DIST = libnss_db.map
+
+ slib_LTLIBRARIES = libnss_db.la
+ libnss_db_la_SOURCES = db-alias.c db-ethers.c db-netgrp.c db-grp.c db-proto.c \
+- db-pwd.c db-rpc.c db-service.c db-spwd.c db-compat.c db-open.c
++ db-pwd.c db-rpc.c db-service.c db-spwd.c db-compat.c db-open.c \
++ db-initgroups.c
+ EXTRA_libnss_db_la_SOURCES = libnss_db.map db-XXX.c \
+ files-ethers.c files-grp.c files-parse.c files-proto.c files-pwd.c \
+ files-rpc.c files-service.c files-spwd.c
+--- a/src/nss_db.h.initgr 2011-04-21 13:37:16.346212000 -0400
++++ b/src/nss_db.h 2011-04-21 14:22:05.644573000 -0400
+@@ -31,4 +31,25 @@ extern enum nss_status internal_setent (
+ /* Close the database *DBP. */
+ extern void internal_endent (DB **dbp, DB_ENV **dbenvp);
+
++
++/* The following are defined in glibc in include/alloca.h. */
++extern int __libc_alloca_cutoff (size_t size) __attribute__ ((const));
++#define PTHREAD_STACK_MIN 16384
++#define __libc_use_alloca(size) \
++ (__builtin_expect ((size) <= PTHREAD_STACK_MIN / 4, 1) \
++ || __libc_alloca_cutoff (size))
++#if defined __i386__ || defined __x86_64__
++# define extend_alloca(buf, len, newlen) \
++ (__typeof (buf)) ({ size_t __newlen = (newlen); \
++ char *__newbuf = alloca (__newlen); \
++ if (__newbuf + __newlen == (char *) buf) \
++ len += __newlen; \
++ else \
++ len = __newlen; \
++ __newbuf; })
++#else
++# define extend_alloca(buf, len, newlen) \
++ alloca (((len) = (newlen)))
++#endif
++
+ #endif /* nss_db.h */
+--- a/src/libnss_db.map.initgr 2011-04-26 15:31:20.775659000 -0400
++++ b/src/libnss_db.map 2011-04-26 15:31:42.134332000 -0400
+@@ -14,6 +14,7 @@
+ _nss_db_setaliasent; _nss_db_setetherent; _nss_db_setgrent;
+ _nss_db_setnetgrent; _nss_db_setprotoent; _nss_db_setpwent;
+ _nss_db_setrpcent; _nss_db_setservent; _nss_db_setspent;
++ _nss_db_initgroups_dyn;
+ local:
+ *;
+ };
diff --git a/nss_db.spec b/nss_db.spec
index a50962d..627abbe 100644
--- a/nss_db.spec
+++ b/nss_db.spec
@@ -4,7 +4,7 @@
Summary: An NSS library for the Berkeley DB
Name: nss_db
Version: 2.2.3
-Release: 0.4.pre1%{?dist}
+Release: 0.5.pre1%{?dist}
Source: ftp://sources.redhat.com/pub/glibc/old-releases/nss_db-%{version}pre1.tar.gz
Source1: http://download.oracle.com/berkeley-db/db-%{db_version}.tar.gz
Source2: db-getent-Makefile
@@ -22,6 +22,7 @@ Patch9: nss_db-2.2-lib64.patch
Patch10: nss_db-2.2-glibc.patch
Patch11: nss_db-2.2-makedb-atomic.patch
Patch12: 200-set-db-environment.patch
+Patch13: d-nss_db-initgr.patch
Patch100: db-4.6.18-glibc.patch
Patch101: http://www.oracle.com/technology/products/berkeley-db/db/update/4.6.21/patch.4.6.21.1
Patch102: http://www.oracle.com/technology/products/berkeley-db/db/update/4.6.21/patch.4.6.21.2
@@ -66,6 +67,7 @@ pushd src
%patch11 -p1 -b .makedb-atomic
popd
%patch12 -p1 -b .set-db-environment
+%patch13 -p1 -b .initgr
cp %{_datadir}/gettext/config.rpath .
rm -f config.guess config.sub ltmain.sh
autoreconf -i
@@ -137,6 +139,12 @@ rm -rf ${RPM_BUILD_ROOT}
%config(noreplace) /var/db/Makefile
%changelog
+* Wed May 18 2011 Nalin Dahyabhai <nalin at redhat.com> - 2.2.3-0.5.pre1
+- import patch to handle initgroups directly rather than forcing libc to
+ use the enumeration interfaces, which could result in two threads calling
+ initgroups() at the same time to both get a subset of the right answers
+ (#705466)
+
* Tue Feb 08 2011 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 2.2.3-0.4.pre1
- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
More information about the scm-commits
mailing list