[24228] in Source-Commits

home help back first fref pref prev next nref lref last post

/svn/athena r23829 - in trunk/debathena/debathena/libnss-nonlocal: . debian

daemon@ATHENA.MIT.EDU (Anders Kaseorg)
Sun May 24 18:00:17 2009

Date: Sun, 24 May 2009 18:00:05 -0400
From: Anders Kaseorg <andersk@MIT.EDU>
Message-Id: <200905242200.n4OM05mG014266@drugstore.mit.edu>
To: source-commits@mit.edu
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Author: andersk
Date: 2009-05-24 18:00:05 -0400 (Sun, 24 May 2009)
New Revision: 23829

Modified:
   trunk/debathena/debathena/libnss-nonlocal/configure.ac
   trunk/debathena/debathena/libnss-nonlocal/debian/changelog
   trunk/debathena/debathena/libnss-nonlocal/nonlocal-group.c
   trunk/debathena/debathena/libnss-nonlocal/nonlocal-passwd.c
Log:
In libnss-nonlocal:
  * New upstream version.
    - Corrects an out-of-memory error in the presence of very large local
      groups.


Modified: trunk/debathena/debathena/libnss-nonlocal/configure.ac
===================================================================
--- trunk/debathena/debathena/libnss-nonlocal/configure.ac	2009-05-23 20:03:15 UTC (rev 23828)
+++ trunk/debathena/debathena/libnss-nonlocal/configure.ac	2009-05-24 22:00:05 UTC (rev 23829)
@@ -1,4 +1,4 @@
-AC_INIT([nss_nonlocal], [1.8], [andersk@mit.edu])
+AC_INIT([nss_nonlocal], [1.9], [andersk@mit.edu])
 AC_CANONICAL_TARGET
 AM_INIT_AUTOMAKE([-Wall -Werror foreign])
 

Modified: trunk/debathena/debathena/libnss-nonlocal/debian/changelog
===================================================================
--- trunk/debathena/debathena/libnss-nonlocal/debian/changelog	2009-05-23 20:03:15 UTC (rev 23828)
+++ trunk/debathena/debathena/libnss-nonlocal/debian/changelog	2009-05-24 22:00:05 UTC (rev 23829)
@@ -1,3 +1,11 @@
+libnss-nonlocal (1.9-0debathena1) unstable; urgency=low
+
+  * New upstream version.
+    - Corrects an out-of-memory error in the presence of very large local
+      groups.
+
+ -- Anders Kaseorg <andersk@mit.edu>  Sun, 24 May 2009 17:30:08 -0400
+
 libnss-nonlocal (1.8-0debathena4) unstable; urgency=low
 
   * Only exclude glibc-private for new enough libc6, because old

Modified: trunk/debathena/debathena/libnss-nonlocal/nonlocal-group.c
===================================================================
--- trunk/debathena/debathena/libnss-nonlocal/nonlocal-group.c	2009-05-23 20:03:15 UTC (rev 23828)
+++ trunk/debathena/debathena/libnss-nonlocal/nonlocal-group.c	2009-05-24 22:00:05 UTC (rev 23829)
@@ -97,12 +97,22 @@
     nip = startp;
     fct.ptr = fct_start;
     do {
+    morebuf:
 	if (fct.l == _nss_nonlocal_getgrgid_r)
 	    status = NSS_STATUS_NOTFOUND;
 	else
 	    status = DL_CALL_FCT(fct.l, (gid, &gbuf, buf, buflen, errnop));
-	if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE)
-	    break;
+	if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE) {
+	    free(buf);
+	    buflen *= 2;
+	    buf = malloc(buflen);
+	    if (buf == NULL) {
+		*errnop = ENOMEM;
+		errno = old_errno;
+		return NSS_STATUS_TRYAGAIN;
+	    }
+	    goto morebuf;
+	}
     } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0);
 
     if (status == NSS_STATUS_SUCCESS) {
@@ -117,7 +127,7 @@
 }
 
 enum nss_status
-get_local_group(const char *name, struct group *grp, char *buffer, size_t buflen, int *errnop)
+get_local_group(const char *name, struct group *grp, char **buffer, int *errnop)
 {
     static const char *fct_name = "getgrnam_r";
     static service_user *startp = NULL;
@@ -129,13 +139,12 @@
 			     char *buffer, size_t buflen, int *errnop);
 	void *ptr;
     } fct;
-    struct group gbuf;
-    int n;
+    size_t buflen;
     int old_errno = errno;
 
-    int len = sysconf(_SC_GETGR_R_SIZE_MAX);
-    char *buf = malloc(len);
-    if (buf == NULL) {
+    buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
+    *buffer = malloc(buflen);
+    if (*buffer == NULL) {
 	*errnop = ENOMEM;
 	errno = old_errno;
 	return NSS_STATUS_TRYAGAIN;
@@ -143,56 +152,36 @@
 
     if (fct_start == NULL &&
 	__nss_group_lookup(&startp, fct_name, &fct_start) != 0) {
-	free(buf);
+	free(*buffer);
+	*buffer = NULL;
 	return NSS_STATUS_UNAVAIL;
     }
     nip = startp;
     fct.ptr = fct_start;
     do {
+    morebuf:
 	if (fct.l == _nss_nonlocal_getgrnam_r)
 	    status = NSS_STATUS_NOTFOUND;
 	else
-	    status = DL_CALL_FCT(fct.l, (name, &gbuf, buf, buflen, errnop));
-	if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE)
-	    break;
+	    status = DL_CALL_FCT(fct.l, (name, grp, *buffer, buflen, errnop));
+	if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE) {
+	    free(*buffer);
+	    buflen *= 2;
+	    *buffer = malloc(buflen);
+	    if (*buffer == NULL) {
+		*errnop = ENOMEM;
+		errno = old_errno;
+		return NSS_STATUS_TRYAGAIN;
+	    }
+	    goto morebuf;
+	}
     } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0);
 
-    if (status != NSS_STATUS_SUCCESS)
-	goto get_local_group_done;
-
-    n = snprintf(buffer, buflen, "%s", gbuf.gr_name);
-    if (n < 0 || n >= buflen) {
-	*errnop = ERANGE;
-	status = NSS_STATUS_TRYAGAIN;
-	goto get_local_group_done;
+    if (status != NSS_STATUS_SUCCESS) {
+	free(*buffer);
+	*buffer = NULL;
     }
-    grp->gr_name = buffer;
-    buffer += n;
-    buflen -= n;
 
-    n = snprintf(buffer, buflen, "%s", gbuf.gr_passwd);
-    if (n < 0 || n >= buflen) {
-	*errnop = ERANGE;
-	status = NSS_STATUS_TRYAGAIN;
-	goto get_local_group_done;
-    }
-    grp->gr_passwd = buffer;
-    buffer += n;
-    buflen -= n;
-
-    grp->gr_gid = gbuf.gr_gid;
-
-    if (buflen < sizeof(void *)) {
-	*errnop = ERANGE;
-	status = NSS_STATUS_TRYAGAIN;
-	goto get_local_group_done;
-    }
-    *(void **)buffer = NULL;
-    buffer += sizeof(void *);
-    buflen -= sizeof(void *);
-
- get_local_group_done:
-    free(buf);
     return status;
 }
 
@@ -400,7 +389,6 @@
     struct group local_users_group, nonlocal_users_group;
     gid_t local_users_gid, gid;
     int is_local = 0;
-    int buflen;
     char *buffer;
 
     /* Check that the user is a nonlocal user before adding any groups. */
@@ -412,50 +400,34 @@
 
     int old_errno = errno;
 
-    buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
-    buffer = malloc(buflen);
-    if (buffer == NULL) {
-	*errnop = ENOMEM;
-	errno = old_errno;
-	return NSS_STATUS_TRYAGAIN;
-    }
     status = get_local_group(MAGIC_LOCAL_GROUPNAME,
-			     &local_users_group, buffer, buflen, errnop);
+			     &local_users_group, &buffer, errnop);
     if (status == NSS_STATUS_SUCCESS) {
 	local_users_gid = local_users_group.gr_gid;
-    } else if (status == NSS_STATUS_TRYAGAIN) {
 	free(buffer);
+    } else if (status == NSS_STATUS_TRYAGAIN) {
 	return status;
     } else {
 	syslog(LOG_WARNING, "nss_nonlocal: Group %s does not exist locally!",
 	       MAGIC_LOCAL_GROUPNAME);
 	local_users_gid = -1;
     }
-    free(buffer);
 
     if (is_local) {
 	gid = local_users_gid;
     } else {
-	buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
-	buffer = malloc(buflen);
-	if (buffer == NULL) {
-	    *errnop = ENOMEM;
-	    errno = old_errno;
-	    return NSS_STATUS_TRYAGAIN;
-	}
  	status = get_local_group(MAGIC_NONLOCAL_GROUPNAME,
-				 &nonlocal_users_group, buffer, buflen, errnop);
+				 &nonlocal_users_group, &buffer, errnop);
 	if (status == NSS_STATUS_SUCCESS) {
 	    gid = nonlocal_users_group.gr_gid;
-	} else if (status == NSS_STATUS_TRYAGAIN) {
 	    free(buffer);
+	} else if (status == NSS_STATUS_TRYAGAIN) {
 	    return status;
 	} else {
 	    syslog(LOG_WARNING, "nss_nonlocal: Group %s does not exist locally!",
 		   MAGIC_NONLOCAL_GROUPNAME);
 	    gid = -1;
 	}
-	free(buffer);
     }
 
     if (gid != -1) {

Modified: trunk/debathena/debathena/libnss-nonlocal/nonlocal-passwd.c
===================================================================
--- trunk/debathena/debathena/libnss-nonlocal/nonlocal-passwd.c	2009-05-23 20:03:15 UTC (rev 23828)
+++ trunk/debathena/debathena/libnss-nonlocal/nonlocal-passwd.c	2009-05-24 22:00:05 UTC (rev 23829)
@@ -95,12 +95,22 @@
     nip = startp;
     fct.ptr = fct_start;
     do {
+    morebuf:
 	if (fct.l == _nss_nonlocal_getpwuid_r)
 	    status = NSS_STATUS_NOTFOUND;
 	else
 	    status = DL_CALL_FCT(fct.l, (uid, &pwbuf, buf, buflen, errnop));
-	if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE)
-	    break;
+	if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE) {
+	    free(buf);
+	    buflen *= 2;
+	    buf = malloc(buflen);
+	    if (buf == NULL) {
+		*errnop = ENOMEM;
+		errno = old_errno;
+		return NSS_STATUS_TRYAGAIN;
+	    }
+	    goto morebuf;
+	}
     } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0);
 
     if (status == NSS_STATUS_SUCCESS) {
@@ -146,12 +156,22 @@
     nip = startp;
     fct.ptr = fct_start;
     do {
+    morebuf:
 	if (fct.l == _nss_nonlocal_getpwnam_r)
 	    status = NSS_STATUS_NOTFOUND;
 	else
 	    status = DL_CALL_FCT(fct.l, (user, &pwbuf, buf, buflen, errnop));
-	if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE)
-	    break;
+	if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE) {
+	    free(buf);
+	    buflen *= 2;
+	    buf = malloc(buflen);
+	    if (buf == NULL) {
+		*errnop = ENOMEM;
+		errno = old_errno;
+		return NSS_STATUS_TRYAGAIN;
+	    }
+	    goto morebuf;
+	}
     } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0);
 
     if (status == NSS_STATUS_SUCCESS)


home help back first fref pref prev next nref lref last post