Re: Linux UID/GID 'Feature'

Jim Trocki (trockij@TRANSMETA.COM)
Sun, 11 May 1997 09:19:16 -0700

On Sat, 10 May 1997, David Phillips (phillips@pcisys.net) wrote:

> I mailed this to a friend as a sanity check:
>
> While trying to make a user entry in the /etc/passwd file unrecognized
> so I could demonstrate the use of valid UIDs, I placed a # in front of the UID.

The problem is that when libc was built, NO_SKIP_BAD was not defined. It
appears that NO_SKIP_BAD is *not* the default value, so it's easily
overlooked (unless someone posts to bugtraq!). I don't know what POSIX
says about this, but it's not acceptable behavior for a function that
handles such a delicate situation. I think that NO_SKIP_BAD should
probably be the default.

Here's the code snippet from pwd/pwdread.c of libc-5.3.12 that does the
sanity checking:

info->p.pw_uid = (uid_t) strtol (end + 1, &end, 10);
if (*end != ':')
#ifdef NO_SKIP_BAD
return ( is_nis_entry ? &info->p : NULL );
#else
if (is_nis_entry)
return &info->p;
else
goto restart;
#endif

strtol(3) returns a NULL if it finds a non-decimal character, hence
struct passwd gets a zero in the pw_uid field.

> It seems ideal for a hard to find, back door but given that you must be root
> to write to the passwd file, I have not found a better way to really exploit it.

This is why sysadmins must be extremely careful while editing the
passwd file. Do realize that you still have to give a correct password
in order to get root access this way.

> He also noted that it works the same for GID. We have not taken the time
> to research the problem fully but have tested it on Red Hat 4.1 (2.0.27/2.0.30).

This is not a kernel issue, it's only a libc issue.

----------
Jim Trocki
Computer System and Network Engineer
Transmeta Corporation
Santa Clara, CA
trockij@transmeta.com