[nss-pam-ldapd] Do not overflow large UID/GID values on 32bit architectures

Jakub Hrozek jhrozek at fedoraproject.org
Fri Dec 16 17:51:07 UTC 2011


commit f92f860c66b8519087c7b1608470880377dbcc39
Author: Jakub Hrozek <jhrozek at redhat.com>
Date:   Fri Dec 16 18:48:55 2011 +0100

    Do not overflow large UID/GID values on 32bit architectures

 nss-pam-ldapd-0.7.x-uid-overflow.patch |  174 ++++++++++++++++++++++++++++++++
 nss-pam-ldapd.spec                     |    7 +-
 2 files changed, 180 insertions(+), 1 deletions(-)
---
diff --git a/nss-pam-ldapd-0.7.x-uid-overflow.patch b/nss-pam-ldapd-0.7.x-uid-overflow.patch
new file mode 100644
index 0000000..f41cadc
--- /dev/null
+++ b/nss-pam-ldapd-0.7.x-uid-overflow.patch
@@ -0,0 +1,174 @@
+diff -up nss-pam-ldapd-0.7.14/configure.ac.biguid nss-pam-ldapd-0.7.14/configure.ac
+--- nss-pam-ldapd-0.7.14/configure.ac.biguid	2011-12-16 18:23:12.728169692 +0100
++++ nss-pam-ldapd-0.7.14/configure.ac	2011-12-16 18:24:29.335211970 +0100
+@@ -222,6 +222,7 @@ AC_C_CONST
+ AC_CHECK_FUNCS([sigaction snprintf])
+ AC_CHECK_FUNCS(gethostbyname)
+ AC_SEARCH_LIBS(socket,socket)
++AC_CHECK_FUNCS([strtoul strtoull])
+ AC_CHECK_FUNCS([strcasecmp strncasecmp strchr strcspn strspn strtol])
+ AC_CHECK_FUNCS([malloc realloc])
+ AC_FUNC_FORK
+@@ -230,6 +231,11 @@ AC_FUNC_FORK
+ AC_TYPE_MODE_T
+ AC_TYPE_SIZE_T
+ AC_TYPE_UID_T
++AC_CHECK_SIZEOF(unsigned int)
++AC_CHECK_SIZEOF(unsigned long int)
++AC_CHECK_SIZEOF(unsigned long long int)
++AC_CHECK_SIZEOF(uid_t)
++AC_CHECK_SIZEOF(gid_t)
+ AC_TYPE_PID_T
+ AC_TYPE_INT32_T
+ AC_TYPE_UINT8_T
+diff -up nss-pam-ldapd-0.7.14/nslcd/cfg.c.biguid nss-pam-ldapd-0.7.14/nslcd/cfg.c
+--- nss-pam-ldapd-0.7.14/nslcd/cfg.c.biguid	2011-12-16 18:19:47.354737215 +0100
++++ nss-pam-ldapd-0.7.14/nslcd/cfg.c	2011-12-16 18:19:57.480610621 +0100
+@@ -449,8 +449,9 @@ static void get_uid(const char *filename
+   char *tmp;
+   check_argumentcount(filename,lnr,keyword,get_token(line,token,sizeof(token))!=NULL);
+   /* check if it is a valid numerical uid */
+-  *var=(uid_t)strtol(token,&tmp,0);
+-  if ((*token!='\0')&&(*tmp=='\0'))
++  errno=0;
++  *var=strtouid(token,&tmp,10);
++  if ((*token!='\0')&&(*tmp=='\0')&&(errno==0))
+     return;
+   /* find by name */
+   pwent=getpwnam(token);
+@@ -474,8 +475,9 @@ static void get_gid(const char *filename
+   char *tmp;
+   check_argumentcount(filename,lnr,keyword,get_token(line,token,sizeof(token))!=NULL);
+   /* check if it is a valid numerical gid */
+-  *var=(gid_t)strtol(token,&tmp,0);
+-  if ((*token!='\0')&&(*tmp=='\0'))
++  errno=0;
++  *var=strtogid(token,&tmp,10);
++  if ((*token!='\0')&&(*tmp=='\0')&&(errno==0))
+     return;
+   /* find by name */
+   grent=getgrnam(token);
+diff -up nss-pam-ldapd-0.7.14/nslcd/common.c.biguid nss-pam-ldapd-0.7.14/nslcd/common.c
+--- nss-pam-ldapd-0.7.14/nslcd/common.c.biguid	2011-12-16 18:20:13.916405148 +0100
++++ nss-pam-ldapd-0.7.14/nslcd/common.c	2011-12-16 18:20:20.332324937 +0100
+@@ -147,3 +147,25 @@ int read_address(TFILE *fp,char *addr,in
+   /* we're done */
+   return 0;
+ }
++
++/* provide a strtoui() implementation, similar to strtoul() but returning
++   an range-checked unsigned int instead */
++uint32_t strtoid(const char *nptr,char **endptr,int base)
++{
++  long long val;
++
++  val=strtoll(nptr,endptr,base);
++  if (val>UINT32_MAX)
++  {
++    errno=ERANGE;
++    return UINT32_MAX;
++  }
++  else if (val<0)
++  {
++    errno=EINVAL;
++    return UINT32_MAX;
++  }
++
++  /* If errno was set, we'll pass it back as-is */
++  return (uint32_t) val;
++}
+diff -up nss-pam-ldapd-0.7.14/nslcd/common.h.biguid nss-pam-ldapd-0.7.14/nslcd/common.h
+--- nss-pam-ldapd-0.7.14/nslcd/common.h.biguid	2011-12-16 18:20:27.333237411 +0100
++++ nss-pam-ldapd-0.7.14/nslcd/common.h	2011-12-16 18:20:58.588846664 +0100
+@@ -25,6 +25,7 @@
+ #define NSLCD__COMMON_H 1
+ 
+ #include <errno.h>
++#include <stdint.h>
+ 
+ #include "nslcd.h"
+ #include "common/nslcd-prot.h"
+@@ -94,6 +95,11 @@ MYLDAP_ENTRY *uid2entry(MYLDAP_SESSION *
+ /* transforms the uid into a DN by doing an LDAP lookup */
+ MUST_USE char *uid2dn(MYLDAP_SESSION *session,const char *uid,char *buf,size_t buflen);
+ 
++#define strtouid (uid_t)strtoid
++#define strtogid (uid_t)strtoid
++
++uint32_t strtoid(const char *nptr,char **endptr,int base);
++
+ /* these are the functions for initialising the database specific
+    modules */
+ void alias_init(void);
+diff -up nss-pam-ldapd-0.7.14/nslcd/group.c.biguid nss-pam-ldapd-0.7.14/nslcd/group.c
+--- nss-pam-ldapd-0.7.14/nslcd/group.c.biguid	2011-12-16 18:21:47.445235876 +0100
++++ nss-pam-ldapd-0.7.14/nslcd/group.c	2011-12-16 18:21:58.471098034 +0100
+@@ -251,13 +251,20 @@ static int write_group(TFILE *fp,MYLDAP_
+     }
+     for (numgids=0;(gidvalues[numgids]!=NULL)&&(numgids<MAXGIDS_PER_ENTRY);numgids++)
+     {
+-      gids[numgids]=(gid_t)strtol(gidvalues[numgids],&tmp,0);
++      errno=0;
++      gids[numgids]=strtogid(gidvalues[numgids],&tmp,10);
+       if ((*(gidvalues[numgids])=='\0')||(*tmp!='\0'))
+       {
+         log_log(LOG_WARNING,"group entry %s contains non-numeric %s value",
+                             myldap_get_dn(entry),attmap_group_gidNumber);
+         return 0;
+       }
++      else if (errno!=0)
++      {
++        log_log(LOG_WARNING,"group entry %s contains too large %s value",
++                            myldap_get_dn(entry),attmap_group_gidNumber);
++        return 0;
++      }
+     }
+   }
+   /* get group passwd (userPassword) (use only first entry) */
+diff -up nss-pam-ldapd-0.7.14/nslcd/passwd.c.biguid nss-pam-ldapd-0.7.14/nslcd/passwd.c
+--- nss-pam-ldapd-0.7.14/nslcd/passwd.c.biguid	2011-12-16 18:22:12.893917723 +0100
++++ nss-pam-ldapd-0.7.14/nslcd/passwd.c	2011-12-16 18:22:20.938817149 +0100
+@@ -338,13 +338,20 @@ static int write_passwd(TFILE *fp,MYLDAP
+     }
+     for (numuids=0;(numuids<MAXUIDS_PER_ENTRY)&&(tmpvalues[numuids]!=NULL);numuids++)
+     {
+-      uids[numuids]=(uid_t)strtol(tmpvalues[numuids],&tmp,0);
++      errno=0;
++      uids[numuids]=strtouid(tmpvalues[numuids],&tmp,10);
+       if ((*(tmpvalues[numuids])=='\0')||(*tmp!='\0'))
+       {
+         log_log(LOG_WARNING,"passwd entry %s contains non-numeric %s value",
+                             myldap_get_dn(entry),attmap_passwd_uidNumber);
+         return 0;
+       }
++      else if (errno!=0)
++      {
++        log_log(LOG_WARNING,"passwd entry %s contains too large %s value",
++                            myldap_get_dn(entry),attmap_passwd_uidNumber);
++        return 0;
++      }
+     }
+   }
+   /* get the gid for this entry */
+@@ -355,13 +362,20 @@ static int write_passwd(TFILE *fp,MYLDAP
+                         myldap_get_dn(entry),attmap_passwd_gidNumber);
+     return 0;
+   }
+-  gid=(gid_t)strtol(gidbuf,&tmp,0);
++  errno=0;
++  gid=strtogid(gidbuf,&tmp,10);
+   if ((gidbuf[0]=='\0')||(*tmp!='\0'))
+   {
+     log_log(LOG_WARNING,"passwd entry %s contains non-numeric %s value",
+                         myldap_get_dn(entry),attmap_passwd_gidNumber);
+     return 0;
+   }
++  else if (errno!=0)
++  {
++    log_log(LOG_WARNING,"passwd entry %s contains too large %s value",
++                        myldap_get_dn(entry),attmap_passwd_uidNumber);
++    return 0;
++  }
+   /* get the gecos for this entry */
+   attmap_get_value(entry,attmap_passwd_gecos,gecos,sizeof(gecos));
+   /* get the home directory for this entry */
diff --git a/nss-pam-ldapd.spec b/nss-pam-ldapd.spec
index 9df2649..e719f2f 100644
--- a/nss-pam-ldapd.spec
+++ b/nss-pam-ldapd.spec
@@ -14,7 +14,7 @@
 
 Name:		nss-pam-ldapd
 Version:	0.7.14
-Release:	1%{?dist}
+Release:	2%{?dist}
 Summary:	An nsswitch module which uses directory servers
 Group:		System Environment/Base
 License:	LGPLv2+
@@ -26,6 +26,7 @@ Source3:	nslcd.tmpfiles
 Source4:	nslcd.service
 Patch1:		nss-pam-ldapd-0.7.13-validname.patch
 Patch2:		nss-pam-ldapd-0.7.x-dnssrv.patch
+Patch3:		nss-pam-ldapd-0.7.x-uid-overflow.patch
 BuildRoot:	%{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildRequires:	openldap-devel, krb5-devel
 BuildRequires:	autoconf, automake
@@ -60,6 +61,7 @@ nsswitch module.
 %setup -q
 %patch1 -p0 -b .validname
 %patch2 -p1 -b .dnssrv
+%patch3 -p1 -b .overflow
 autoreconf -f -i
 
 %build
@@ -259,6 +261,9 @@ exit 0
 %endif
 
 %changelog
+* Fri Dec 16 2011 Jakub Hrozek <jhrozek at redhat.com> 0.7.14-2
+- Do not overflow large UID/GID values on 32bit architectures
+
 * Mon Nov 28 2011 Nalin Dahyabhai <nalin at redhat.com>
 - use the same conditional test for deciding when to create the .so symlink as
   we do later on for deciding when to include it in the package (#757004)


More information about the scm-commits mailing list