Blame SOURCES/nss-pam-ldapd-0.8.12-uid-overflow.patch

09a3f6
Always use a function that we know will catch out-of-range values for UIDs and
09a3f6
GIDs, which are currently unsigned 32-bit numbers everywhere, and which won't
09a3f6
produce a result that'll silently be truncated if we store the result in a
09a3f6
uid_t or gid_t.
09a3f6
--- nss-pam-ldapd/nslcd/common.c
09a3f6
+++ nss-pam-ldapd/nslcd/common.c
09a3f6
@@ -273,19 +273,23 @@ long int binsid2id(const char *binsid)
09a3f6
          ((((long int)binsid[i+2])&0xff)<<16)|((((long int)binsid[i+3])&0xff)<<24);
09a3f6
 }
09a3f6
 
09a3f6
-#ifdef WANT_STRTOUI
09a3f6
-/* provide a strtoui() implementation, similar to strtoul() but returning
09a3f6
+/* provide a strtoid() implementation, similar to strtoul() but returning
09a3f6
    an range-checked unsigned int instead */
09a3f6
-unsigned int strtoui(const char *nptr,char **endptr,int base)
09a3f6
+unsigned int strtoid(const char *nptr,char **endptr,int base)
09a3f6
 {
09a3f6
-  unsigned long val;
09a3f6
-  val=strtoul(nptr,endptr,base);
09a3f6
-  if (val>UINT_MAX)
09a3f6
+  long long val;
09a3f6
+  /* use the fact that long long is 64-bit, even on 32-bit systems */
09a3f6
+  val=strtoll(nptr,endptr,base);
09a3f6
+  if (val>UINT32_MAX)
09a3f6
   {
09a3f6
     errno=ERANGE;
09a3f6
-    return UINT_MAX;
09a3f6
+    return UINT32_MAX;
09a3f6
   }
09a3f6
-  /* If errno was set by strtoul, we'll pass it back as-is */
09a3f6
-  return (unsigned int)val;
09a3f6
+  else if (val < 0)
09a3f6
+  {
09a3f6
+    errno=EINVAL;
09a3f6
+    return UINT32_MAX;
09a3f6
+  }
09a3f6
+  /* If errno was set, we'll pass it back as-is */
09a3f6
+  return (uint32_t)val;
09a3f6
 }
09a3f6
-#endif /* WANT_STRTOUI */
09a3f6
--- nss-pam-ldapd/nslcd/common.h
09a3f6
+++ nss-pam-ldapd/nslcd/common.h
09a3f6
@@ -139,31 +139,9 @@ int nsswitch_db_uses_ldap(const char *fi
09a3f6
 #endif /* _POSIX_HOST_NAME_MAX */
09a3f6
 #endif /* not HOST_NAME_MAX */
09a3f6
 
09a3f6
-/* provide strtouid() function alias */
09a3f6
-#if SIZEOF_UID_T == SIZEOF_UNSIGNED_LONG_INT
09a3f6
-#define strtouid (uid_t)strtoul
09a3f6
-#elif SIZEOF_UID_T == SIZEOF_UNSIGNED_LONG_LONG_INT
09a3f6
-#define strtouid (uid_t)strtoull
09a3f6
-#elif SIZEOF_UID_T == SIZEOF_UNSIGNED_INT
09a3f6
-#define WANT_STRTOUI 1
09a3f6
-#define strtouid (uid_t)strtoui
09a3f6
-#else
09a3f6
-#error unable to find implementation for strtouid()
09a3f6
-#endif
09a3f6
-
09a3f6
-/* provide strtouid() function alias */
09a3f6
-#if SIZEOF_GID_T == SIZEOF_UNSIGNED_LONG_INT
09a3f6
-#define strtogid (gid_t)strtoul
09a3f6
-#elif SIZEOF_GID_T == SIZEOF_UNSIGNED_LONG_LONG_INT
09a3f6
-#define strtogid (gid_t)strtoull
09a3f6
-#elif SIZEOF_GID_T == SIZEOF_UNSIGNED_INT
09a3f6
-#ifndef WANT_STRTOUI
09a3f6
-#define WANT_STRTOUI 1
09a3f6
-#endif
09a3f6
-#define strtogid (uid_t)strtoui
09a3f6
-#else
09a3f6
-#error unable to find implementation for strtogid()
09a3f6
-#endif
09a3f6
+uint32_t strtoid(const char *nptr,char **endptr,int base);
09a3f6
+#define strtouid (uid_t)strtoid
09a3f6
+#define strtogid (gid_t)strtoid
09a3f6
 
09a3f6
 #ifdef WANT_STRTOUI
09a3f6
 /* provide a strtoui() if it is needed */