From owner-freebsd-security Wed Nov 29 03:19:38 1995 Return-Path: owner-security Received: (from root@localhost) by freefall.freebsd.org (8.6.12/8.6.6) id DAA02855 for security-outgoing; Wed, 29 Nov 1995 03:19:38 -0800 Received: from sivka.carrier.kiev.ua (root@sivka.carrier.kiev.ua [193.125.68.130]) by freefall.freebsd.org (8.6.12/8.6.6) with ESMTP id DAA02760 for ; Wed, 29 Nov 1995 03:18:34 -0800 Received: from elvisti.kiev.ua (uucp@localhost) by sivka.carrier.kiev.ua (Sendmail 8.who.cares/5) with UUCP id NAA02155 for security@freebsd.org; Wed, 29 Nov 1995 13:15:24 +0200 Received: from office.elvisti.kiev.ua (office.elvisti.kiev.ua [193.125.28.33]) by spider2.elvisti.kiev.ua (8.6.12/8.ElVisti) with ESMTP id MAA28875 for ; Wed, 29 Nov 1995 12:01:33 +0200 Received: (from stesin@localhost) by office.elvisti.kiev.ua (8.6.12/8.ElVisti) id MAA15889 for security@freebsd.org; Wed, 29 Nov 1995 12:01:31 +0200 From: "Andrew V. Stesin" Message-Id: <199511291001.MAA15889@office.elvisti.kiev.ua> Subject: Re: chroot/setuid vs type enforcement (fwd) To: security@freebsd.org Date: Wed, 29 Nov 1995 12:01:31 +0200 (EET) X-Mailer: ELM [version 2.4 PL24alpha5] Content-Type: text Content-Length: 5204 Sender: owner-security@freebsd.org Precedence: bulk Here are interesting thoughts about hardening security of chrooted environment... Forwarded message: # From: "Marcus J. Ranum" # Message-Id: <199511290431.XAA20148@switchblade.iwi.com> # Subject: Re: chroot/setuid vs type enforcement # To: jeromie@garrison.com # Date: Tue, 28 Nov 1995 23:31:00 -0500 (EST) # Cc: firewalls@GreatCircle.COM, mjr@iwi.com # Organization: Information Warehouse! Inc, Baltimore, MD # Phone: 410-889-8569 # Coredump: Infocalypse Now!!! # # jeromie@garrison.com writes: # > As far as being able to remove system calls from accessibility, I would # >like to hear about if any firewalls have done this. Removing the system calls # >from accessibility would limit potential vulerabilities. # # It's not hard to do; you simply comment them out of the kernel # or appropriately modify the kernel. I staunchly refuse to accept that # these things are rocket science, or even very difficult; the kernel # is just a program and if you are smart enough to use a system you can # get source for then it's easy to fix. # # Let's examine one possiblity. Suppose I am using chroot() to # protect my firewall. And the argument I want to make is that I want # to be sure, for sure, that nobody can tweak a buffer overrun and # call a socket from inside the chrooted area. # # [This is all from BSDI/NetBSD.] # uipc_syscalls.c, at around line 79, has the source code # for the socket() system call. vfs_syscalls.c, at around line 613 # has the source code for the chroot() system call. # # You'll notice, in chroot() that the proc struct (the process # table slot) for each process has the vnode of the process' root # file system in it. That's hung off the p->p_fd, which is the # process' file descriptor table - which in turn stores the # root vnode as p->p_fd->fd_rdir. With me so far? :) # # Now, there's a vnode that's stashed away (see vfs_lookup # and the system init code in init_main.c) and it's called "rootvnode." # Given it's name, you won't be shocked to discover that it's the # root filesystem's "top" vnode. # # So - we can assume that if a process' root vnode is not # the same as the system's root vnode, then it's been chrooted. TA-DA! # It actually may be simpler than that, since line 127 of vfs_lookup.c # implies that processes which have NOT been chrooted have a root # vnode of NULL: # # if ((ndp->ni_rootdir = fdp->fd_rdir) == NULL) # ndp->ni_rootdir = rootvnode; # # Let's assume that's correct. Now we "harden" our kernel # by altering the socket() system call thusly: # # uipc_syscalls.c line 78: # # if(p->fdp->fr_rdir != NULL) # return(EPERM); # # WHOAH! It took me 24 lines to explain it, and 2 to code it! # What this means is that a chrooted process that does a socket() will # get a permission denied. Maybe that's a bit too brute force. We # might want to put the code into connect() instead and only let the # process connect to localhost - or whatever. You get the idea. This # is trivial code that takes minutes to implement. # # The *TRICK* is implementing the RIGHT code in the RIGHT # place. For this example, if I put it in socket() - what about other # forms of IPC? See - I'd need to be darn careful to cover all the # angles. That's nothing to do with the formal properties of my # protection model; that's a simple matter of Getting The Code Right # and Damn The Formal Handwaving. # # >In summary, the strongest feature touted by sctc is that chroot() is vulerable # >to buffer overflows. In my eyes, this means that if a proxy were to get # >subverted, it would not take much to subvert the chroot() setuid() calls and # >gain full access over the firewall. I would like to hear if anyone has # >comments on this issue..?? # # Chroot() is not "vulnerable to buffer overflows" -- processes # that have chrooted are potentially vulnerable to buffer overflows. # # Subverting a chroot() that has been correctly combined with # a setuid() is *HARD* - if the chroot() area is set up correctly and # the kernel is implemented correctly, and your system doesn't # automatically trust connections from itself, then you are not going # to be able to do a lot of damage. But, as I've shown above, there # are lots of ways to address that kind of thing. You can make it # impossible to break out of a chroot simply by setuid()ing to a non # root user - then you are no longer permitted to chroot again. If # there's no way in the chroot area to get privs, then there's no # way out other than via a socket - and you can nail that dead with # 2 lines of code. # # The easiest way, however, is to be REAL careful about not # having buffer overruns in your code. :) # # This whole game is about being REAL careful about your code. # Whether it's code in the kernel or code in user space, it's just # code. Because someone's waved the orange-book over the hacks they # made to the kernel doesn't make them any fancier than the kind of # hackery I described above (but for sure they're better documented!) # # mjr. # -- With best regards -- Andrew Stesin. +380 (44) 2760188 +380 (44) 2713457 +380 (44) 2713560 An undocumented feature is a coding error.