OSEC

Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com
 
Subject: Re: Demo patch - run telnetd as non-root and chroot()'ed
From: Pavel Kankovsky (peakargo.troja.mff.cuni.cz)
Date: Sat Jul 22 2000 - 13:22:47 CDT


On Thu, 20 Jul 2000, Chris Evans wrote:

> I really think this is the direction Linux security needs to go in. After
> all, a thorough audit may still miss holes, so why not make them
> moderately irrelevant?

We all (should) know there is no silver-bullet solution but any extra
line of defense is a good thing...as long as the price (financial
expenses + performance penalty + inconvenience etc.) is acceptable.

> + /* Currently 5 env. vars allowed */
> + char envbuf[256*5];
> + int todo = sizeof(envbuf);
> + char* ptr = envbuf;
> +
> + /* {ce} - Before we consider launching login, we need to nab any
> + * import environment variables the unprivileged client wants to
> + * send
> + */
> + while(todo > 0)
> + {

This is one of the moments you wish Linux had a decent message passing
mechanism like all those "academic OSes" Linus hates so much, isn't it? :)

> + /* {ce} - Make a pipe to communicate from no-priv protocol parser
> + * to privileged /bin/login launching child.
> + * We need the communication to pass environment variables which
> + * /bin/login needs to inherit
> + */
> + pipe(pipefds);

This is one of the places where a return value ought to be checked.
(pipefds would stay less or more unitialized if pipe() failed and very
interesting things could happen)

> + struct passwd* pw;
> + pw = getpwnam("telnetd");
> + if (pw == NULL)
> + {
> + /* Bah */
> + pw = getpwnam("nobody");
> + }
> + if (pw != NULL)

This is not fail-safe. If an attacker could stress the machine enough to
cause a temporary failure of getpwnam() (unfortunately, it is impossible
to tell whether getpwnam() returned NULL because the user in question did
not exist or because something went wrong), the process would not drop
any privileges.

> + /* Before we drop root */
> + /* XXX - poor. Need /var/empty in FSSTND */
> + chdir("/tmp");
> + chroot(".");
> +
> + initgroups(pw->pw_name, pw->pw_gid);

initgroups() needs /etc/group. It will not work in a chroot'ed
environment.

--Pavel Kankovsky aka Peak [ Boycott Microsoft--http://www.vcnet.com/bms ]
"Resistance is futile. Open your source code and prepare for assimilation."