diff -ruN shadow-4.2.1/libmisc/idmapping.c shadow-4.2.1.new/libmisc/idmapping.c
--- shadow-4.2.1/libmisc/idmapping.c 2014-03-01 19:59:51.000000000 +0100
+++ shadow-4.2.1.new/libmisc/idmapping.c 2016-07-19 10:55:49.339097323 +0200
@@ -77,6 +77,11 @@
return NULL;
if (!getulong(argv[argidx + 2], &mapping->count))
return NULL;
+
+ if (ULONG_MAX - mapping->upper <= mapping->count || ULONG_MAX - mapping->lower <= mapping->count) {
+ fprintf(stderr, _( "%s: subuid overflow detected.\n"), Prog);
+ exit(EXIT_FAILURE);
+ }
}
return mappings;
}
diff -ruN shadow-4.2.1/libmisc/myname.c shadow-4.2.1.new/libmisc/myname.c
--- shadow-4.2.1/libmisc/myname.c 2014-03-01 19:59:51.000000000 +0100
+++ shadow-4.2.1.new/libmisc/myname.c 2016-07-19 10:14:49.298852058 +0200
@@ -44,25 +44,13 @@
/*@null@*/ /*@only@*/struct passwd *get_my_pwent (void)
{
struct passwd *pw;
- const char *cp = getlogin ();
uid_t ruid = getuid ();
- /*
- * Try getlogin() first - if it fails or returns a non-existent
- * username, or a username which doesn't match the real UID, fall
- * back to getpwuid(getuid()). This should work reasonably with
- * usernames longer than the utmp limit (8 characters), as well as
- * shared UIDs - but not both at the same time...
+ /* Do not use getlogin(). Its not suitable for suid binaries.
*
* XXX - when running from su, will return the current user (not
* the original user, like getlogin() does). Does this matter?
*/
- if ((NULL != cp) && ('\0' != *cp)) {
- pw = xgetpwnam (cp);
- if ((NULL != pw) && (pw->pw_uid == ruid)) {
- return pw;
- }
- }
return xgetpwuid (ruid);
}
diff -ruN shadow-4.2.1/lib/getulong.c shadow-4.2.1.new/lib/getulong.c
--- shadow-4.2.1/lib/getulong.c 2014-03-01 18:50:05.000000000 +0100
+++ shadow-4.2.1.new/lib/getulong.c 2016-07-19 10:36:14.476785123 +0200
@@ -44,22 +44,19 @@
*/
int getulong (const char *numstr, /*@out@*/unsigned long int *result)
{
- long long int val;
+ unsigned long int val;
char *endptr;
errno = 0;
- val = strtoll (numstr, &endptr, 0);
+ val = strtoul (numstr, &endptr, 0);
if ( ('\0' == *numstr)
|| ('\0' != *endptr)
|| (ERANGE == errno)
- /*@+ignoresigns@*/
- || (val != (unsigned long int)val)
- /*@=ignoresigns@*/
) {
return 0;
}
- *result = (unsigned long int)val;
+ *result = val;
return 1;
}