Friday, September 18, 2009

Cool things with SELinux... Introducing sandbox -X

One of the downsides of working in security is that we seldom get to do cool things.  The desktop engineers, VM engineers, even kernel engineers get to  show off cool stuff.  But security guys usually only ever get to show how we  broke something, if that.  Sometimes all we can do is say "trust us, it's working." But I think I have something cool to show off which I'm calling  sandbox -X.

A little history.

Back in May, I wrote a blog entry describing the "SELinux Sandbox", , which provides a way to run a filter-type program within a locked-down sandbox. This allows administrators to take untrusted content, run it through one or more filters, and be able to trust that the content can't cause the filter programs to do evil things.

As soon as I released it, I received email asking if It could be used to sandbox Acroread, and I had to say "Sorry, it can't do that".  

But why can't it do that?

Acroread and  most other desktop applications use multiple communication channels, interacting not just with stdin and stdout, but accessing configuration files, directly or using interprocess calls as with GConf, the X server and other applications, and usually have full run of the user's home directory.  A bug in a desktop application can be exploited to attack other processes on the system through any of these channels.  Attempting to lock down access to these things usually just causes applications to break, or at least degrades the user experience.  In a nutshell, there was no good,  general-purpose way to lock down Acroread, or that matter, any other desktop application.

Over the years several attempts have been made to lock down Desktop apps, most of which have failed.  I have often discouraged policy writers from attempting to write policy to lock down Firefox.  The main reason for this is the difficulty of locking down various information flows described above.  Tools like firefox are expected to be able to read and write all over the homedir and need pretty full access to X. 

SELinux is all about defining security goals. 

For example I might have a security goal that firefox application will not send email.  So I can check if my policy prevents firefox from sending email.  But my security goal can change depending on the content that I want to look at.  For whatever reason, I might want to allow OpenOffice to have full access to everything in my homedir when I launch it from the start menu, but when it  is launched from firefox on untrusted content, I only want OpenOffice to be able to display, print, or email that content, not my credit card data....

I introduced xguest a year or so ago, and I've thought about why people liked the concept and the ways people were telling me they were using it.  (Xguest is the least privileged user, his homedir is cleared on exit, and he is only able to connect to http ports).  I have been told that some people use xguest to go to untrusted sites where they do not want to have bad data left behind. Others have told me they use xguest to run games, to make sure the downloaded games aren't allowed to do evil things.

How could I build a usable "xguest" tool that did this on an app by app basis?

I started working on sandbox -X. 

The first step was to create a new $HOMEDIR and new /tmp, and mount them over the real $HOMEDIR and /tmp.
  • sandbox -X creates new empty directories in the $HOMEDIR and /tmp
  • It labels these sandbox_x_file_t:MCS where MCS is a randomly selected MCS label
  • it then execs seunshare, specifying the new HOMEDIR and new /tmp, as well as an SELinux context and the command to run
  • /usr/sbin/seunshare is a new setuid C Program
    • seunshare calls unshare (2) to  disassociate mount names from the process execution context,
    • seunshare bind-mounts the sandbox HOMEDIR and /tmp these over the current $HOMEDIR and /tmp
    • seunshare then execs the shell under a sandbox_x_t:MCS context
  • When seunshare exits, sandbox  -X destroys the contents of the temporary $HOMEDIR and /tmp
  • sandbox_x_t policy prevents anything running in the sandbox from using the network, touching any user home content, allowing it to only read/write to sandox_x_file_t, basically locking it down.
But what about X?
  • I decided not to use the X Access Control Extension (XAce) to provide separation since I could never achieve the separation I wanted using it. 
  • I use Xephyr to start a whole new X server.  This prevents XClients running within Xephyr from talking directly to the host X Server.
  • I also use a window manager Matchbox which maximizes the app to the size of the xserver.
This gives me a fully locked down desktop session, in which I can run almost any X client application.

Here are some examples

sandbox -X evince ~/Documents/RedHat/selinux_four_things.pdf

This sandbox -X session is running evince inside of a sandbox.  The sandbox tool actually copied the content into the new HOMEDIR so that evince could see it.

> sandbox -X xterm

This example lets me explore the locked down environment sandbox -X provides. Note that while I am still running with my UID, I am no longer running under unconfined_t, but under sandbox_x_client_t:so:c17,c355.  There are no files in my sandboxed home directory.  When I try to run a privileged command like sudo I'm not allowed to, and if I try to ssh our or send email, I'll be denied. I do allow sandbox_x_t to connect to the printer ports to allow the evince example above to be able to print, but I do not allow it to connect to most other network ports. 

What if I want to use sandbox to confine my Firefox session?

You can specify an alternate SELinux type. For Fedora 12 the sandbox_web_t to allow you to run firefox. sandbox_net_t is also available, which allows full network access.

> sandbox -X -t sandbox_web_t firefox

You can even write your own policy, if you want.

allow sandbox_MYAPP_client_t self:tcp_socket create_socket_perms;

Now I think that is cool... What do you think?

How do I try it out?

Install Raw Hide, or Fedora 12 when it comes out.  Install the policycoreutils-sandbox package if it is not installed.  (Sorry, but after you install the package you will need to reboot to set up the mount space sharing.)  As a user, run:

sandbox -X COMMAND

There are some things I would like to see improved here. 
  • The main thing is that the Xephyr window is not resizable, so after the apps starts the app can not be resized.  Maybe the X team will fix this, or provide a rootless X on X server, which would let us allow sandboxed applications to at least communicate with each other.
  • Cut and Paste does not work, But then, that's kind of the idea.
  • NFS home directories do not currently work since NFS does not support labeling.
  • This tool can generate lots of AVC's if you try to do evil stuff within your sandbox.
Future goals:
  • We would like to have the sandbox tool prompt you if any of the input to the sandbox has changed, so the user could decide whether or not to save the input. 
  • Maybe allow sandbox to specify only a shared subdirectory of the users homedir, where the sandbox would be allowed to write.  You could say allow OpenOffice to save to ~/sandboxout
Other ideas welcome.

No comments:

Post a Comment