[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

r4087 - in glibc-package/branches/glibc-branch-etch/debian: . patches patches/any



Author: aurel32
Date: 2010-01-16 15:26:47 +0000 (Sat, 16 Jan 2010)
New Revision: 4087

Added:
   glibc-package/branches/glibc-branch-etch/debian/patches/any/submitted-nis-shadow.diff
Modified:
   glibc-package/branches/glibc-branch-etch/debian/changelog
   glibc-package/branches/glibc-branch-etch/debian/patches/series
Log:
  * Fix NIS shadow entries leakage to non-priviledge users when nscd is
    in use.
    Fixes: CVE-2010-0015.



Modified: glibc-package/branches/glibc-branch-etch/debian/changelog
===================================================================
--- glibc-package/branches/glibc-branch-etch/debian/changelog	2010-01-16 14:54:09 UTC (rev 4086)
+++ glibc-package/branches/glibc-branch-etch/debian/changelog	2010-01-16 15:26:47 UTC (rev 4087)
@@ -1,3 +1,11 @@
+glibc (2.3.6.ds1-13etch10) stable; urgency=low
+
+  * Fix NIS shadow entries leakage to non-priviledge users when nscd is
+    in use.
+    Fixes: CVE-2010-0015.
+
+ -- Aurelien Jarno <aurel32@debian.org>  Sat, 16 Jan 2010 16:26:38 +0100
+
 glibc (2.3.6.ds1-13etch9) stable; urgency=low
 
   * Backport from unstable: patches/localedata/cy_EL_euro.diff,

Added: glibc-package/branches/glibc-branch-etch/debian/patches/any/submitted-nis-shadow.diff
===================================================================
--- glibc-package/branches/glibc-branch-etch/debian/patches/any/submitted-nis-shadow.diff	                        (rev 0)
+++ glibc-package/branches/glibc-branch-etch/debian/patches/any/submitted-nis-shadow.diff	2010-01-16 15:26:47 UTC (rev 4087)
@@ -0,0 +1,339 @@
+2010-01-06  Christoph Pleger <Christoph.Pleger@cs.tu-dortmund.de>
+	    Aurelien Jarno  <aurelien@aurel32.net>
+
+	* nis/nss_nis/nis-pwd.c (internal_nis_getpwent_r): When adjunct
+	style secret password is returned, mangle 'x' instead of the
+	encrypted password.
+	(_nss_nis_getpwnam_r): Likewise.
+	(_nss_nis_getpwuid_r): Likewise.
+	* nis/nss_nis/nis-spwd.c (internal_nis_getspent_r): When shadow.byname
+	does not exist, look in passwd.adjunct.byname and adapt the result.
+	(_nss_nis_getspnam_r): Likewise.
+
+
+--- a/nis/nss_nis/nis-pwd.c
++++ b/nis/nss_nis/nis-pwd.c
+@@ -82,9 +82,8 @@
+   do
+     {
+       enum nss_status retval;
+-      char *result, *outkey, *result2, *p;
+-      int len, keylen, len2;
+-      size_t namelen;
++      char *result, *outkey, *p;
++      int len, keylen;
+ 
+       if (new_start)
+         retval = yperr2nss (yp_first (domain, "passwd.byname",
+@@ -105,44 +104,33 @@
+ 	 recognized by a password starting with "##".  */
+       p = strchr (result, ':');
+       if (p != NULL	/* This better should be true in all cases.  */
+-	  && p[1] == '#' && p[2] == '#'
+-	  && (namelen = p - result,
+-	      yp_match (domain, "passwd.adjunct.byname", result, namelen,
+-			&result2, &len2)) == YPERR_SUCCESS)
++	  && p[1] == '#' && p[2] == '#')
+ 	{
+-	  /* We found a passwd.adjunct entry.  Merge encrypted
+-	     password therein into original result.  */
+-	  char *encrypted = strchr (result2, ':');
+-	  char *endp;
+-	  size_t restlen;
++	  size_t namelen, restlen;
+ 
+-	  if (encrypted == NULL
+-	      || (endp = strchr (++encrypted, ':')) == NULL
+-	      || (p = strchr (p + 1, ':')) == NULL)
++	  namelen = p - result;
++	  if ((p = strchr (p + 1, ':')) == NULL)
+ 	    {
+ 	      /* Invalid format of the entry.  This never should happen
+ 		 unless the data from which the NIS table is generated is
+ 		 wrong.  We simply ignore it.  */
+-	      free (result2);
+ 	      goto non_adjunct;
+ 	    }
+ 
++	  /* We found an adjunct style secret password.  Replace
++	     it by 'x' into the result.  */
+ 	  restlen = len - (p - result);
+-	  if ((size_t) (namelen + (endp - encrypted) + restlen + 2) > buflen)
++	  if ((size_t) (namelen + restlen + 3) > buflen)
+ 	    {
+-	      free (result2);
+ 	      free (result);
+ 	      *errnop = ERANGE;
+ 	      return NSS_STATUS_TRYAGAIN;
+ 	    }
+ 
+-	  __mempcpy (__mempcpy (__mempcpy (__mempcpy (buffer, result, namelen),
+-					   ":", 1),
+-				encrypted, endp - encrypted),
++	  __mempcpy (__mempcpy (__mempcpy (buffer, result, namelen),
++				":x", 2),
+ 		     p, restlen + 1);
+ 	  p = buffer;
+-
+-	  free (result2);
+ 	}
+       else
+ 	{
+@@ -201,8 +189,8 @@
+ {
+   struct parser_data *data = (void *) buffer;
+   enum nss_status retval;
+-  char *domain, *result, *result2, *p;
+-  int len, len2, parse_res;
++  char *domain, *result, *p;
++  int len, parse_res;
+   size_t namelen;
+ 
+   if (name == NULL)
+@@ -230,43 +218,32 @@
+      by a password starting with "##".  */
+   p = strchr (result, ':');
+   if (p != NULL	/* This better should be true in all cases.  */
+-      && p[1] == '#' && p[2] == '#'
+-      && yp_match (domain, "passwd.adjunct.byname", name, namelen,
+-		   &result2, &len2) == YPERR_SUCCESS)
++      && p[1] == '#' && p[2] == '#')
+     {
+-      /* We found a passwd.adjunct entry.  Merge encrypted password
+-	 therein into original result.  */
+-      char *encrypted = strchr (result2, ':');
+-      char *endp;
+       size_t restlen;
+-
+-      if (encrypted == NULL
+-	  || (endp = strchr (++encrypted, ':')) == NULL
+-	  || (p = strchr (p + 1, ':')) == NULL)
++      
++      if ((p = strchr (p + 1, ':')) == NULL)
+ 	{
+ 	  /* Invalid format of the entry.  This never should happen
+ 	     unless the data from which the NIS table is generated is
+ 	     wrong.  We simply ignore it.  */
+-	  free (result2);
+ 	  goto non_adjunct;
+ 	}
+ 
++      /* We found an adjunct style secret password.  Replace
++         it by 'x' into the result.  */
+       restlen = len - (p - result);
+-      if ((size_t) (namelen + (endp - encrypted) + restlen + 2) > buflen)
++      if ((size_t) (namelen + restlen + 3) > buflen)
+ 	{
+-	  free (result2);
+ 	  free (result);
+ 	  *errnop = ERANGE;
+ 	  return NSS_STATUS_TRYAGAIN;
+ 	}
+ 
+-      __mempcpy (__mempcpy (__mempcpy (__mempcpy (buffer, name, namelen),
+-				       ":", 1),
+-			    encrypted, endp - encrypted),
++      __mempcpy (__mempcpy (__mempcpy (buffer, name, namelen),
++			    ":x", 2),
+ 		 p, restlen + 1);
+       p = buffer;
+-
+-      free (result2);
+     }
+   else
+     {
+@@ -304,10 +281,9 @@
+ {
+   struct parser_data *data = (void *) buffer;
+   enum nss_status retval;
+-  char *domain, *result, *p, *result2;
+-  int len, nlen, parse_res, len2;
++  char *domain, *result, *p;
++  int len, nlen, parse_res;
+   char buf[32];
+-  size_t namelen;
+ 
+   if (yp_get_default_domain (&domain))
+     return NSS_STATUS_UNAVAIL;
+@@ -328,44 +304,32 @@
+      by a password starting with "##".  */
+   p = strchr (result, ':');
+   if (p != NULL	/* This better should be true in all cases.  */
+-      && p[1] == '#' && p[2] == '#'
+-      && (namelen = p - result,
+-	  yp_match (domain, "passwd.adjunct.byname", result, namelen,
+-		    &result2, &len2)) == YPERR_SUCCESS)
++      && p[1] == '#' && p[2] == '#')
+     {
+-      /* We found a passwd.adjunct entry.  Merge encrypted password
+-	 therein into original result.  */
+-      char *encrypted = strchr (result2, ':');
+-      char *endp;
+-      size_t restlen;
++      size_t namelen, restlen;
+ 
+-      if (encrypted == NULL
+-	  || (endp = strchr (++encrypted, ':')) == NULL
+-	  || (p = strchr (p + 1, ':')) == NULL)
++      namelen = p - result;
++      if ((p = strchr (p + 1, ':')) == NULL)
+ 	{
+ 	  /* Invalid format of the entry.  This never should happen
+ 	     unless the data from which the NIS table is generated is
+ 	     wrong.  We simply ignore it.  */
+-	  free (result2);
+ 	  goto non_adjunct;
+ 	}
+-
++      /* We found an adjunct style secret password.  Replace
++	 it by 'x' into the result.  */
+       restlen = len - (p - result);
+-      if ((size_t) (namelen + (endp - encrypted) + restlen + 2) > buflen)
++      if ((size_t) (namelen + restlen + 3) > buflen)
+ 	{
+-	  free (result2);
+ 	  free (result);
+ 	  *errnop = ERANGE;
+ 	  return NSS_STATUS_TRYAGAIN;
+ 	}
+ 
+-      __mempcpy (__mempcpy (__mempcpy (__mempcpy (buffer, result, namelen),
+-				       ":", 1),
+-			    encrypted, endp - encrypted),
++      __mempcpy (__mempcpy (__mempcpy (buffer, result, namelen),
++			    ":x", 2),
+ 		 p, restlen + 1);
+       p = buffer;
+-
+-      free (result2);
+     }
+   else
+     {
+--- a/nis/nss_nis/nis-spwd.c
++++ b/nis/nss_nis/nis-spwd.c
+@@ -78,25 +78,51 @@
+   /* Get the next entry until we found a correct one. */
+   do
+     {
+-      enum nss_status retval;
+       char *p;
++      int yperr;
++      int adjunct_used = 0;
+ 
+       if (new_start)
+-        retval = yperr2nss (yp_first (domain, "shadow.byname",
+-                                      &outkey, &keylen, &result, &len));
++	{
++          yperr = yp_first (domain, "shadow.byname", &outkey, &keylen, &result,
++			    &len);
++
++	  if (yperr == YPERR_MAP)
++	    {
++	      if (result != NULL)
++		free(result);
++
++	      yperr = yp_first (domain, "shadow.byname", &outkey, &keylen,
++				&result, &len);
++	      adjunct_used = 1;
++	    }
++        }
+       else
+-        retval = yperr2nss ( yp_next (domain, "shadow.byname",
+-                                      oldkey, oldkeylen,
+-                                      &outkey, &keylen, &result, &len));
++	{
++          yperr = yp_next (domain, "shadow.byname", oldkey, oldkeylen, &outkey,
++			   &keylen, &result, &len);
+ 
+-      if (retval != NSS_STATUS_SUCCESS)
++	  if (yperr == YPERR_MAP)
++	    {
++	      if (result != NULL)
++		free(result);
++
++	      yperr = yp_next (domain, "shadow.byname", oldkey, oldkeylen,
++			       &outkey, &keylen, &result, &len); 
++	      adjunct_used = 1;
++	    }
++        }
++
++      if (yperr != YPERR_SUCCESS)
+         {
++	  enum nss_status retval = yperr2nss (yperr);
++
+ 	  if (retval == NSS_STATUS_TRYAGAIN)
+ 	    *errnop = errno;
+           return retval;
+         }
+ 
+-      if ((size_t) (len + 1) > buflen)
++      if ((size_t) (len + (adjunct_used ? 3 : 1)) > buflen)
+         {
+           free (result);
+ 	  *errnop = ERANGE;
+@@ -105,6 +131,9 @@
+ 
+       p = strncpy (buffer, result, len);
+       buffer[len] = '\0';
++      if (adjunct_used)
++	p = strcat (buffer, "::");
++
+       while (isspace (*p))
+         ++p;
+       free (result);
+@@ -147,9 +176,9 @@
+ 		     char *buffer, size_t buflen, int *errnop)
+ {
+   struct parser_data *data = (void *) buffer;
+-  enum nss_status retval;
+   char *domain, *result, *p;
+-  int len, parse_res;
++  int len, parse_res, yperr;
++  int adjunct_used = 0;
+ 
+   if (name == NULL)
+     {
+@@ -160,17 +189,29 @@
+   if (yp_get_default_domain (&domain))
+     return NSS_STATUS_UNAVAIL;
+ 
+-  retval = yperr2nss (yp_match (domain, "shadow.byname", name,
+-				strlen (name), &result, &len));
++  yperr = yp_match (domain, "shadow.byname", name, strlen (name), &result,
++		    &len);
+ 
+-  if (retval != NSS_STATUS_SUCCESS)
++  if (yperr == YPERR_MAP)
++    {
++      if (result != NULL)
++	free(result);
++
++      yperr = yp_match (domain, "passwd.adjunct.byname", name, strlen (name),
++			&result, &len);
++      adjunct_used = 1;
++  }
++
++  if (__builtin_expect (yperr != YPERR_SUCCESS, 0))
+     {
++      enum nss_status retval = yperr2nss (yperr);
++
+       if (retval == NSS_STATUS_TRYAGAIN)
+ 	*errnop = errno;
+       return retval;
+     }
+ 
+-  if ((size_t) (len + 1) > buflen)
++  if ((size_t) (len + (adjunct_used ? 3 : 1)) > buflen)
+     {
+       free (result);
+       *errnop = ERANGE;
+@@ -179,6 +220,9 @@
+ 
+   p = strncpy (buffer, result, len);
+   buffer[len] = '\0';
++  if (adjunct_used)
++    p = strcat (buffer, "::");
++
+   while (isspace (*p))
+     ++p;
+   free (result);

Modified: glibc-package/branches/glibc-branch-etch/debian/patches/series
===================================================================
--- glibc-package/branches/glibc-branch-etch/debian/patches/series	2010-01-16 14:54:09 UTC (rev 4086)
+++ glibc-package/branches/glibc-branch-etch/debian/patches/series	2010-01-16 15:26:47 UTC (rev 4087)
@@ -201,3 +201,4 @@
 any/cvs-vfprintf-stack-smashing.diff
 any/cvs-getnetgrent_r-memory-leak.diff
 any/cvs-sunrpc_rpc_thread.diff -p0
+any/submitted-nis-shadow.diff -p1


Reply to: