At 01:55 PM 14/11/97 +1100, Darren Reed wrote:


>No.  If it can write to /dev/kmem (especially), then all it needs to 
do

>is call the mknod(2) system call, create the right device for
/dev/kmem,

>open it, search for the right place in memory to change and voila! No

>more chroot'd environment.  Most of the buffer exploits for programs

>could be converted to do that or make it possible.


suppose I don't have a /dev/kmem - see LINUX

suppose I don't have a /dev in my chroot()'d environment

suppose I have a /dev/kmem in my chroot'd environment which is 

        actually /dev/null



Why oh why would you set up a chroot'd environment with

the ability to break out of it, by supplying things like a compiler,

syscall library..... 


There is also a very simple kernel tweek you can make.

If the per process root inode is not the same as the system

inode (i.e. the process is running chroot()'d) then disallow

various system calls.   I can claim originality for this....


It occurred in


<paraindent><param>left</param>From: "Marcus J. Ranum" <<mjr@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

Reply-To: mjr@iwi.com

Organization: Information Warehouse! Inc, Baltimore, MD

URL: <<A HREF="http://iwi.com/mjr/mjr-top.html">mjr's web page<</A>

Phone: 410-889-8569

Coredump: Infocalypse Now!!!

Sender: firewalls-owner@GreatCircle.COM

</paraindent>

Where he said (sorry this is so long, I've cut some of the discussion
out

to leave the meat).


<paraindent><param>left</param>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.

</paraindent>

<paraindent><param>left</param>[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.

</paraindent>

<paraindent><param>left</param>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.


</paraindent>Hoever his really important point is that things have to be 

set up properly or this is all redundant.   Having /dev/kmem

in your chroot()'d are is NOT setting things up properly!


<paraindent><param>left</param>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.


</paraindent>Personally, as an old kernel hacker, I'd put the code
earlier.

I'd have the check made right after entry to a syscall interrupt 
handler

and either have a second dispatch table or a column in the table saying

whether this can be executed when croot'd or not.   This has the
advantage of

localizing the changes and making them more visible.  But then I'm also

partial to table driven code ;-)  perhaps those flags would also indicate
if

you need to be root to execute that system call.  I can imagine a 
simple

piece of code that says if you're chroot()'d you can't do any 
privileged

calls.


My point is that the arguments about breaking out of chroot jail so far
have

assumed it hasn't been set up properly.  I don't want to play an infinite 

regression of "yes....but" games, but saying you can break out if a
certain

hole exists just means add for checking for that hole to you setup 
list.

And the holes presented so far are not impressive.


/anton






## Reply End ##

--------------------------------------------------------------------------

Anton J Aylward                  | "Quality refers to the extent to which 

The Strahn & Strachan Group Inc  | processes, products, services, and 

Information Security Consultants | relationships are free from defects, 

Voice: (416) 421-8182            | constraints and items which do not add

  Fax: (416) 421-8183            | value." - Dr. Mildred G Pryor, 1995 


