Author: aurel32
Date: 2010-01-07 23:13:35 +0000 (Thu, 07 Jan 2010)
New Revision: 4071

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



Modified: glibc-package/branches/glibc-branch-lenny/debian/changelog
===================================================================
--- glibc-package/branches/glibc-branch-lenny/debian/changelog  2010-01-07 
22:13:13 UTC (rev 4070)
+++ glibc-package/branches/glibc-branch-lenny/debian/changelog  2010-01-07 
23:13:35 UTC (rev 4071)
@@ -1,3 +1,11 @@
+glibc (2.7-18lenny2) stable-security; urgency=low
+
+  * Fix NIS shadow entries leakage to non-priviledge users when nscd is
+    in use.
+    Fixes: CVE-2010-XXXX.
+
+ -- Aurelien Jarno <aure...@debian.org>  Fri, 08 Jan 2010 00:10:10 +0100
+
 glibc (2.7-18lenny1) stable; urgency=low
 
   * patches/any/cvs-realloc.diff: fix bug in realloc() when enlarging a

Added: 
glibc-package/branches/glibc-branch-lenny/debian/patches/any/submitted-nis-shadow.diff
===================================================================
--- 
glibc-package/branches/glibc-branch-lenny/debian/patches/any/submitted-nis-shadow.diff
                              (rev 0)
+++ 
glibc-package/branches/glibc-branch-lenny/debian/patches/any/submitted-nis-shadow.diff
      2010-01-07 23:13:35 UTC (rev 4071)
@@ -0,0 +1,304 @@
+2010-01-06  Christoph Pleger <christoph.ple...@cs.tu-dortmund.de>
+           Aurelien Jarno  <aurel...@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.
+
+diff --git a/nis/nss_nis/nis-pwd.c b/nis/nss_nis/nis-pwd.c
+index fdc7dc9..efb5c61 100644
+--- a/nis/nss_nis/nis-pwd.c
++++ b/nis/nss_nis/nis-pwd.c
+@@ -266,49 +266,32 @@ internal_nis_getpwent_r (struct passwd *pwd, char 
*buffer, size_t buflen,
+       /* Check for adjunct style secret passwords.  They can be
+        recognized by a password starting with "##".  */
+       char *p = strchr (result, ':');
+-      size_t namelen;
+-      char *result2;
+-      int len2;
+       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;
+-
+-        if (encrypted == NULL
+-            || (endp = strchr (++encrypted, ':')) == NULL
+-            || (p = strchr (p + 1, ':')) == NULL)
++        size_t 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;
+           }
+ 
+-        restlen = len - (p - result);
+-        if (__builtin_expect ((size_t) (namelen + (endp - encrypted)
+-                                        + restlen + 2) > buflen, 0))
++        /* We found an adjunct style secret password.  Replace
++           it by 'x' into the result.  */
++        size_t restlen = len - (p - result);
++        if (__builtin_expect ((namelen + restlen + 3) > buflen, 0))
+           {
+-            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
+       {
+@@ -400,47 +383,33 @@ _nss_nis_getpwnam_r (const char *name, struct passwd 
*pwd,
+ 
+   /* Check for adjunct style secret passwords.  They can be recognized
+      by a password starting with "##".  */
+-  char *result2;
+-  int len2;
+   char *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;
+-
+-      if (encrypted == NULL
+-        || (endp = strchr (++encrypted, ':')) == NULL
+-        || (p = strchr (p + 1, ':')) == NULL)
++      size_t 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.  */
+       size_t restlen = len - (p - result);
+-      if (__builtin_expect ((size_t) (namelen + (endp - encrypted)
+-                                    + restlen + 2) > buflen, 0))
++      if (__builtin_expect ((namelen + restlen + 3) > buflen, 0))
+       {
+-        free (result2);
+         free (result);
+         *errnop = ERANGE;
+         return NSS_STATUS_TRYAGAIN;
+       }
+ 
+-      __mempcpy (__mempcpy (__mempcpy (__mempcpy (buffer, name, namelen),
+-                                     ":", 1),
+-                          encrypted, endp - encrypted),
+-               p, restlen + 1);
++      mempcpy (mempcpy (mempcpy (buffer, result, namelen),
++                      ":x", 2),
++             p, restlen + 1);
+       p = buffer;
+-
+-      free (result2);
+     }
+   else
+     {
+@@ -499,50 +468,33 @@ _nss_nis_getpwuid_r (uid_t uid, struct passwd *pwd,
+ 
+   /* Check for adjunct style secret passwords.  They can be recognized
+      by a password starting with "##".  */
+-  char *result2;
+-  int len2;
+-  size_t namelen;
+   char *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;
+-
+-      if (encrypted == NULL
+-        || (endp = strchr (++encrypted, ':')) == NULL
+-        || (p = strchr (p + 1, ':')) == NULL)
++      size_t 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;
+       }
+ 
+-      restlen = len - (p - result);
+-      if (__builtin_expect ((size_t) (namelen + (endp - encrypted)
+-                                    + restlen + 2) > buflen, 0))
++      /* We found an adjunct style secret password.  Replace
++       it by 'x' into the result.  */
++      size_t restlen = len - (p - result);
++      if (__builtin_expect ((namelen + restlen + 3) > buflen, 0))
+       {
+-        free (result2);
+         free (result);
+         *errnop = ERANGE;
+         return NSS_STATUS_TRYAGAIN;
+       }
+ 
+-      __mempcpy (__mempcpy (__mempcpy (__mempcpy (buffer, result, namelen),
+-                                     ":", 1),
+-                          encrypted, endp - encrypted),
+-               p, restlen + 1);
++      mempcpy (mempcpy (mempcpy (buffer, result, namelen),
++                      ":x", 2),
++             p, restlen + 1);
+       p = buffer;
+-
+-      free (result2);
+     }
+   else
+     {
+diff --git a/nis/nss_nis/nis-spwd.c b/nis/nss_nis/nis-spwd.c
+index 0fc4e17..9bd1ad6 100644
+--- a/nis/nss_nis/nis-spwd.c
++++ b/nis/nss_nis/nis-spwd.c
+@@ -81,13 +81,38 @@ internal_nis_getspent_r (struct spwd *sp, char *buffer, 
size_t buflen,
+       int len;
+       int keylen;
+       int yperr;
++      int adjunct_used = 0;
+ 
+       if (new_start)
+-        yperr = 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, "passwd.adjunct.byname", &outkey, 
&keylen,
++                              &result, &len);
++            adjunct_used = 1;
++          }
++      }
+       else
+-        yperr = yp_next (domain, "shadow.byname", oldkey, oldkeylen, &outkey,
+-                       &keylen, &result, &len);
++      {
++        yperr = yp_next (domain, "shadow.byname", oldkey, oldkeylen, &outkey,
++                         &keylen, &result, &len);
++
++        if (yperr == YPERR_MAP)
++          {
++            if (result != NULL)
++                free(result);
++
++            yperr = yp_next (domain, "passwd.adjunct.byname", oldkey, 
oldkeylen,
++                             &outkey, &keylen, &result, &len);
++            adjunct_used = 1;
++          }
++      }
+ 
+       if (__builtin_expect (yperr != YPERR_SUCCESS, 0))
+         {
+@@ -98,7 +123,7 @@ internal_nis_getspent_r (struct spwd *sp, char *buffer, 
size_t buflen,
+           return retval;
+         }
+ 
+-      if (__builtin_expect ((size_t) (len + 1) > buflen, 0))
++      if (__builtin_expect ((size_t) (len + (adjunct_used ? 3 : 1)) > buflen, 
0))
+         {
+           free (result);
+         *errnop = ERANGE;
+@@ -107,6 +132,9 @@ internal_nis_getspent_r (struct spwd *sp, char *buffer, 
size_t buflen,
+ 
+       char *p = strncpy (buffer, result, len);
+       buffer[len] = '\0';
++      if (adjunct_used)
++        p = strcat (buffer, "::");
++
+       while (isspace (*p))
+         ++p;
+       free (result);
+@@ -149,6 +177,8 @@ enum nss_status
+ _nss_nis_getspnam_r (const char *name, struct spwd *sp,
+                    char *buffer, size_t buflen, int *errnop)
+ {
++  int adjunct_used = 0;
++
+   if (name == NULL)
+     {
+       *errnop = EINVAL;
+@@ -164,6 +194,16 @@ _nss_nis_getspnam_r (const char *name, struct spwd *sp,
+   int yperr = yp_match (domain, "shadow.byname", name, strlen (name), &result,
+                       &len);
+ 
++  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);
+@@ -173,7 +213,7 @@ _nss_nis_getspnam_r (const char *name, struct spwd *sp,
+       return retval;
+     }
+ 
+-  if (__builtin_expect ((size_t) (len + 1) > buflen, 0))
++  if (__builtin_expect ((size_t) (len + (adjunct_used ? 3 : 1)) > buflen, 0))
+     {
+       free (result);
+       *errnop = ERANGE;
+@@ -182,6 +222,9 @@ _nss_nis_getspnam_r (const char *name, struct spwd *sp,
+ 
+   char *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-lenny/debian/patches/series
===================================================================
--- glibc-package/branches/glibc-branch-lenny/debian/patches/series     
2010-01-07 22:13:13 UTC (rev 4070)
+++ glibc-package/branches/glibc-branch-lenny/debian/patches/series     
2010-01-07 23:13:35 UTC (rev 4071)
@@ -232,3 +232,4 @@
 any/local-missing-linux_types.h.diff
 any/submitted-user_h.diff -p1
 any/cvs-realloc.diff -p1
+any/submitted-nis-shadow.diff -p1


-- 
To UNSUBSCRIBE, email to debian-glibc-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to