Subject: RootRunner (admin GUI w/o security holes?)
To: None <tech-security@NetBSD.ORG>
From: Jake Hamby <jehamby@manta.jpl.nasa.gov>
List: tech-security
Date: 07/10/1998 14:18:47
Hi all,

I'm currently working on an administration GUI tool for FreeBSD, Linux,
and Solaris.  I've bitten off a rather large chunk of features that I'd
like to implement before my deadline of August 15, but I hope to implement
at least basic user, group, network, and package management.  While I
don't plan to do a NetBSD port myself, certainly this should be trivial,
and I'll gladly incorporate whatever patches are needed to make it run on
NetBSD.  The GUI will be written in KDE, though, so keep that it mind.

Anyway, in order to administer a UNIX system, you typically need root
privileges.  Yet it's a Bad Idea to run X as root.  Looking at other GUI
admin tools, I've seen two basic approaches.  First, many require the user
to su to root before running the tool, or else it works in read-only mode. 
This is ugly because it's difficult to run the program from your window
manager, so you have to pop open an xterm, su to root, then run it if
you're logged in as yourself. Yet, this is the approach that many programs
take, especially on Linux.

The other approach is even worse, from a security standpoint.  This is to
make the program setuid root, and ask the user for the root password if
necessary.  I don't need to mention the problems this presents if any
security holes (such as buffer overflow exploits or simply not thoroughly
checking the user's privileges) are discovered in the program.  This is
the approach taken by many commercial UNIXs, including IRIX and Solaris,
and a quick search of Bugtraq will reveal tons of holes from this alone.

I came up with an idea for my admin program that I haven't seen before,
yet (like the recent poster of the chroot jail program), I strongly
suspect I may be reinventing the wheel.  My idea is to open a pty, spawn
/bin/sh, then execute the su (or sudo, if installed) program, query the
user from the GUI for the root password, and feed it through the pty. 
Then I'll have a root shell that I can execute commands in, including the
ability to read/write administration files (by using cat).  This sounds
ideal to me, because the program (including the GUI, which is important
considering the recent security holes discovered in Xlib) runs as the
user, and the only setuid program needed is /bin/su (which *better* be
secure, or else the entire system is in a lot of trouble :). 

Even better, my program will (optionally) show the user which commands
it's executing, and as much as possible, use the tools in /sbin and
/usr/sbin rather than directly talking to the OS.  The only other program
I've heard of that works this way is SMIT on AIX, and it sounds very
useful.  I can simply echo the output of each command to a subwindow of
the GUI and in the process, teach the actual UNIX commands to new
sysadmins, rather than hiding it from them.  Are there any potential
security holes with this approach? 

The first problem I can think of is that the program might crash, leaving
the root password in the core file.  However, since all good UNIXes set
the permissions on cores to 600, and the user who ran the program must've
known the root password in order for it to be saved, then this seems like
a reasonable risk.  I considered installing a signal handler for SIGSEGV
and other common signals that dump core, then wiping all occurrence of the
root password, but due to the vagaries of GUIs and even stdio, I can't
guarantee that it won't be lying around somewhere.  I could prevent the
program from dumping core, but if there are any bugs in the GUI, I want to
know about them and be able to get a stack backtrace from gdb, so for now
at least, that's out of the question.

Is there any possibility (especially in BSD and Linux, which require you
to search the /dev/ptyXX space to find an open pty), for race conditions
where an eavesdropper could get the root password through the pty when
someone else is running the admin GUI?  Any pointers on how to write this
section of the code (if it would need to be any different from the way
that, for example, xterm grabs a pty) would be helpful.

I plan to finish my implementation and release it, hopefully tonight, in
which case I'll post a URL.  I'd really appreciate it if any of you have
time for a quick walkthrough of my code to make sure it doesn't do
anything stupid.  Please reply by private email if you have any comments. 
I'll summarize them and post to the list when finished.  Also, if you can
think of other mailing lists I should post this to, that would be very
helpful. 

My version of "RootRunner" will use C++ and Qt, so unfortunately, probably
won't be directly useful to many of you.  However, I will release it under
a liberal BSD-style copyright, so feel free to modify it for your own
needs, especially since I think the concept could be very useful for all
sorts of programs which need to run (at least temporarily) as another
user, including (eek!) competitors to mine.

-Jake