Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 9 Jul 1997 12:09:35 -0400 (EDT)
From:      Robert Watson <robert@cyrus.watson.org>
To:        Mark Newton <newton@communica.com.au>
Cc:        newton@communica.com.au, sef@kithrup.com, security@FreeBSD.ORG
Subject:   Re: Security Model/Target for FreeBSD or 4.4?
Message-ID:  <Pine.BSF.3.95q.970709112726.175A-100000@cyrus.watson.org>
In-Reply-To: <9707090029.AA06358@communica.com.au>

next in thread | previous in thread | raw e-mail | index | archive | help

> Study the code carefully in light of this discussion.  Realize that
> providing arbitrary users with the ability to run chroot() would allow
> arbitrary users to break out of sandboxen.  Examine the patch I posted
> and see how it prevents the scenario listed above, at the sacrifice
> of a certain amount of existing functionality (I'm not arguing that
> the patch be made standard;  I'm just happy to have it available for
> those building firewalls and such who might actually need it).
> 
> Finally, I've been having trouble getting a clear idea of what you're 
> trying to achieve here.  I suspect that you have a specific case in 
> mind where providing arbitrary users with the ability to chroot() would
> solve a problem you've been having.  If so, perhaps presenting the 
> problem instead of putting the solution first might be helpful in this
> discussion, and might enable ConcernedReaders to propose a solution that
> doesn't involve fundamental redesign (design?  not really.  re-frobbing :-)
> of a standard kernel facility that is heavily relied upon in security-
> critical environments.
> 
> What applications do you see that'd be more readily implemented if 
> arbitrary users could chroot()?
> 
>     - mark
>       [ oh, for the old days, when "chroot" meant "cigar," and life
>         was that much simpler <grin> ]
> 

Thank you for your detailed response and description of the chroot()
security issues :).  I've spent a significant amount of time working in
the network security area, but other than as an administrator, not much
time on internal issues.  I appreciate your clarification of the existing
code, and explanations.

My interest in making chroot() a general-purpose facility stem from the
following concerns:

Programs should be able to impose restrictions on their own execution,
allowing them to reduce the impact of their running on the system (e.g.,
setting their nice level higher, or restricting memory allocation), or for
security purposes, where the programmer has the best intentions, but
cannot garuntee that their code cannot be exploited.  If a programmer can
restrict the execution of their code to a specific disk area, they have a
useful tool.  Currently, programs that provide network services and wish
to execute in a chroot() environment must be run as root, then seteuid() 
(is that the correct call) to return to the userid they are intended to
run as. 

Similarly, programs that serve complex network services (such as WWW
services) benefit from a chroot() environment.  It's popular, for example,
to have ftpd or httpd run in chroot(), as enough problems have been found
with these pieces of software that chroot() can make a significant
difference in their security.  This is especially the case where cgi
programs are executed, as the system administrator may not want arbitrary
user programs run by the web server to have access to the entire system.
Right now, all these programs begin execution as root anyway (they must be
root to bind <1024, or because they change userid's based on
authentication.)  In the case of the web server, if chroot() is only
offered to uid 0 programs, I have the following choice:

1. Run the server as root, have it bind, chroot, and then seteuid to the
www user

2. Run the server as www, have it bind the port (now permitted), but lose
the added security of chroot().

Web servers have suffered from security problems for both running as root,
and for having general file system access.  Other servers suffer
similarly.  In the case of a commercial web server (not unusual) where the
source code is not available, I'm not sure I want to trust their program
to correctly give up root access on running, although I do want it to
benefit from chroot() and the ability to bind tcp port 80.

A few other examples: should a mail server running as user mail have
access to the entire file system?  It no longer has to run as root because
it can bind port 25 by itself (as authorized), and, except for local mail
delivery, it doesn't require access to anywhere in the file system but
/var/mqueue (and possibly some other config, statistics, user-info files.)
Some simple rewriting of sendmail based on running as non-root, and having
user-chroot() would be of great benefit.

It seems like a fairly simple arguement: I have a server program that
provides information on calendar schedules over the network to interested
clients.  It cannot benefit from access to the entire file system (it has
/home/calendar/ as its entire tree of information and responses.)  It
could do harm to the system if it did have such access.  If a suitable
security policy is to provide only the rights that are needed to perform
the required actions, shouldn't we provide a user facility for this?  As a
developer, I suspect I should not have to ask my system administrator to
make a program suid to take advantage of this.

Another example might be a web browser: with the advent of Java, the
concept of a "sandbox" for arbitrary program execution has become very
popular.  But we are consistently finding holes in web browsers, and in
the sandboxes, and currently proposals exist to weaken the sandbox.  It's
easy to answer "if you don't like the behavior of the software, don't run
it", but that doesn't make it easier for the administrator of a
distributed networking environment to maintain a reasonable version of
Netscape across 200 machines.  For normal browsing, Java applet execution,
there is no reason to allow Netscape read access to my /etc directory, or
write access to /usr/tmp.

That the current implementation of the chroot() call is not suitable for
this use doesn't make the concept of a user-chroot() any less useful. :)
As a software designer, I should take every precaution when designing my
code that it cannot be abused, but when developing extremely large
projects (named, sendmail, httpd) involving many programmers, and much
contributed code, I also cannot rely on their being no problems at all.
In this case, having the operating system provide some level of buffering
might be helpful.  A user chroot would presumably have greater
limitations, or might prevent the execution of suid(), for example.  It
might only be available to non-root programs.  Are there limitations that
could address all of the problems with allowing users to access the uid0
chroot() call we currently are aware of?

A question about the creation of hard links: what are the advantages of
allowing uid 1000 to create a hard link in his directory to /usr/sbin/su,
owned by uid 0?  Hard links seem to be a useful facility, but are they
commonly used between uids?

Robert Watson




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.3.95q.970709112726.175A-100000>