Capsicum Kernel

I’ve been looking at the concept of capability-based security lately with a lot of interest. The idea is to provide an API from the kernel that enforces very granular permissions on processes - thereby limiting the possible damage from a rogue process.

An easy example would be that of the web browser. Google’s Chrome achieves a good level of separation of concerns by spawning processes for each tab, meaning that a poorly behaving tab (usually) can’t crash the entire browser. Unfortunately, this process still has the permissions of the user it is running as. Even with privilege dropping, this still allows access to a user’s personal files - often a fatal problem when dealing with credentials and private documents. In a capability-based system, these child processes could be created such that they can (for instance) only read from a particular directory, or only write to a single file. You can see how this fine-grained level of permissions could really do wonders to help with security on our increasingly sophisticated and malicious web.

The University of Cambridge has developed a modified FreeBSD kernel that implements one such vision of capability-based security, Capsicum. In addition to the required kernel changes and capabilities daemon, there are a number of projects already leveraging these capabilities. Listed on the Capsicum projects page are:

  • libcapsicum - This includes a number of APIs and convenience functions
  • User rights angels - These provide user session based mechanisms for granting capabilities to processes as they are requested
  • Library self-compartmentalization - An ongoing effort to adapt commonly used libraries to execute risky portions of their code in capabilities sandboxes
  • chromium-capsicum - A version of Google’s Chromium web browser enhanced to use capabilities sandboxes (!!!)

Additionally, the FreeBSD implementation includes a number of Capsicum enhanced utilities, such as dhclient, tcpdump, and kdump… lucky devils.

Capsicum ships out-of-the-box with FreeBSD 10.0 and as an optional feature in 9.0, 9.1, and 9.2. Unfortunately, yours truly is a Linux guy. Someday I might venture back into the world of real UNIX, but that day is not today ^_^

Thankfully a Googler named David Drysdale has created a Linux port of the required kernel modifications for Capsicum to run under Linux!

In this post, I’ll document the steps I take to compile the enhanced kernel under Linux (I’m using Ubuntu for this - Arch will be a project for another day). Hopefully this ends in success. Either way, dear reader, you are along for the ride!

First Steps

First things first, let’s grab the source code for the capsicum-linux kernel.

$ git clone https://github.com/google/capsicum-linux

This is a very large repository, so this command will take some time. While you wait, be sure to check on your Nerende buildings and maybe play through a story point :-)

Insert hold music here

Alright, 2 hours later, the git repository is cloned!

Now let’s begin. First, let’s copy over our existing kernel config to the source root:

$ cp /boot/config-`uname -r` .config

Now update the config to match the new source code:

$ make oldconfig

This will ask you questions for newly added config values. The default is generally safe for these. The Capsicum README.md mentioned the following configuration parameters that need to be enabled:

  • CONFIG_64BIT: Capsicum support is currently only implemented for 64 bit mode.
  • CONFIG_PROCDESC: enable Capsicum process-descriptor functionality.
  • CONFIG_SECURITY: enable Linux Security Module (LSM) support.
  • CONFIG_SECURITY_PATH: enable LSM hooks for path operations
  • CONFIG_SECURITY_CAPSICUM: enable the Capsicum LSM.
  • CONFIG_DEFAULT_SECURITY_CAPSICUM, CONFIG_DEFAULT_SECURITY="capsicum": set Capsicum as default LSM.

Additionally, I made the following deviations from the defaults:

  • Kernel compression mode LZMA (KERNEL_LZMA)
  • Process descriptors (PROCDESC) - Y (This is mentioned above as CONFIG_PROCDESC)
  • Memory Resource Controller for Control Groups? - Y (Sounded neat)
  • Memory Resource Controller Swap Extension? - Y (Related to the above)
  • ”” enabled by default? - N (Help text recommends controlling this via boot params)
  • User namespace (USER_NS) - Y (Sounds cool)
  • Compressed cache for swap pages (ZSWAP) - Y (Absolutely!)

After the first ~40 or so questions, I was prompted with a bunch of device driver questions. The values carried over from my current kernel config have been treating me just fine, so I sped through this section, stopping each time the indentation level was zero to see what new section I was in (sound cards, ethernet cards, wireless cards, etc). Be careful not to speed too far through, as following the device drivers we get back into interesting things like kernel debugging and security options. In this section, we reach a capsicum related item again. Be sure to enable SECURITY_CAPSICUM.

Additionally, because I’m a bit of a crypto-fan, I enabled a lot of the optional algorithms. Related to this, I also enabled RANDOM32_SELFTEST to perform a self test of the 32-bit PRNG library functions on initialization.

Update: 11Feb2014 16:45:23 - As long as CONFIG_SECURITY_CAPSICUM=y is present, you are fine

After answering all of the prompts, I noticed that some of the required config options weren’t specifically asked of me. Specifically, make sure CONFIG_SECURITY_CAPSICUM=y, CONFIG_DEFAULT_SECURITY_CAPSICUM=y and CONFIG_DEFAULT_SECURITY="capsicum" are all present in the generated .config file.

In my .config file, CONFIG_DEFAULT_SECURITY_APPARMOR and CONFIG_DEFAULT_SECURITY="apparmor" were both present. Be sure to remove or comment these out if you have any similar values that are not CAPSICUM.

Kick Off The Build!

Now that all of the configuration is done, we are ready to kick off the build! This process will take a long time and is best left running overnight / overlunch.

$ make clean
$ make -j `getconf _NPROCESSORS_ONLN` deb-pkg LOCALVERSION=-capsicum

You can change the “-capsicum” to whatever flavor string you’d like to use for your new kernel.

After issuing the make command above, I was prompted to again choose the default Linux security manager. I grep’d the source code and there was no instance of DEFAULT_SECURITY_CAPSICUM other than the one in the README.md - this may be an outdated instruction. I chose SELinux when prompted.

Update: 11Feb2014 16:46:00 - The prompts above occurred because DEFAULT_SECURITY_CAPSICUM is not defined. As mentioned above, simply having CONFIG_SECURITY_CAPSICUM=y in the .config file is enough to enable Capsicum in the build

The build is kicked off and I’ll report back for part two tomorrow!