r4071 - in glibc-package/branches/glibc-branch-lenny/debian: . patches patches/any
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 <aurel32@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.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.
+
+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
Reply to: