COMMAND
shadow
SYSTEMS AFFECTED
Linux Slackware 3.2, 3.3, 3.4, 3.5
PROBLEM
Ted Hickman discovered following. He noticed something rather
"insecure" about the slackware 3.4 /bin/login (and probably other
versions). If the /etc/group file does not exist, any user who
logs into the system is given uid 0 gid 0!
buglord login: meek
Password:
initgroups: No such file or directory
Linux 2.0.34.
Last login: Fri Jul 10 20:56:17 on tty6.
You have mail.
buglord:~# id
uid=0(root) gid=0
The following is recorded in the syslog:
Jul 10 22:28:42 buglord login[25795]: initgroups failed for user `meek`:
No such file or directory
Further analysis was done by Richard Thomas. An examination of
shadow-971001 shows the following in libmisc/setugid.c:
/*
* setup_uid_gid() performs the following steps -
*
* set the supplementary group IDs
* optionally call specified function which may add more groups
* set the group ID to the value from the password file entry
* set the user ID to the value from the password file entry
*
* Returns 0 on success, or -1 on failure.
*/
int
setup_uid_gid(info, is_console)
const struct passwd *info;
int is_console;
{
#ifdef HAVE_INITGROUPS
/*
* For systems which support multiple concurrent groups, go get
* the group set from the /etc/group file.
*/
if (initgroups (info->pw_name, info->pw_gid) == -1) {
perror("initgroups");
SYSLOG((LOG_ERR, "initgroups failed for user `%s': %m\n",
info->pw_name));
closelog();
return -1;
}
[snip]
And src/login.c line 960:
setup_uid_gid(&pwent, is_console);
The call to setup_uid_gid() in login.c does no checking of the
return value. If initgroups cannot open /etc/group, the
setup_uid_gid() function returns before it gets around to the
setgid() and setuid() calls (hence the uid and gid are both still
0). No special claims to know what is happening in shadow, but it
appears that they decided to do the calls in setup() individually,
directly in login.c. Seems that if setup_uid_gid is nice enough
to return the success or failure status, the least we could do is
check it (ESPECIALLY since this is also the status of the setgid
and setuid calls!). Why do they still include the setup() function
if its not used? How does this become a security hole? Well if
you can find a way to delete the /etc/group file things could
become rather messy. The file has to actually be non-existent
(chmod 000 won't do it).
SOLUTION
So whats the fix? Well first of all, change src/login.c to:
if (setup_uid_gid(&pwent, is_console))
exit(1);
If we wanted to be fancy we could continue to login even if
initgroups() fails (most likely you don't "need" those extra
groups to get into the system and fix it). With _patch_ above you
can't crate create /etc/group after that (you can, but what
then?). This does not affect RedHat.