[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