Index: shadow-4.2.1/lib/getulong.c =================================================================== --- shadow-4.2.1/lib/getulong.c +++ shadow-4.2.1/lib/getulong.c 2017-01-24 09:21:34.129950205 -0500 @@ -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; } Index: shadow-4.2.1/libmisc/idmapping.c =================================================================== --- shadow-4.2.1/libmisc/idmapping.c +++ shadow-4.2.1/libmisc/idmapping.c 2017-01-24 09:14:55.478472471 -0500 @@ -77,6 +77,10 @@ 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; } Index: shadow-4.2.1/libmisc/myname.c =================================================================== --- shadow-4.2.1/libmisc/myname.c +++ shadow-4.2.1/libmisc/myname.c 2017-01-24 09:19:22.575095103 -0500 @@ -44,26 +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); } -