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>