Capsicum Personal Package Archive

This page explains how to set up an Ubuntu system to experiment with Capsicum on Linux. The Capsicum version of the Linux kernel is experimental and subject to change, so install and use at your own risk. If you are installing into a virtual machine, it's probably a good idea to take a snapshot before proceeding.

Add the Repository

The Capsicum package archive lives at pkg.capsicum-linux.org, and holds packages for Ubuntu Trusty (14.04). The following steps are needed to use the archive.

Install the Kernel

The kernel packages available at the Capsicum archive have been configured similarly to the normal generic Ubuntu kernel, but are built from the main upstream kernel sources, without any Ubuntu/Debian-specific changes. To allow multiple kernels to be installed in parallel, most of the package names include the kernel version.

The final package that is part of the Capsicum kernel build is linux-libc-dev, which holds the header files that are needed for userspace development. This package does not include the kernel version in its name, because later kernel versions are always supposed to be back-compatible with userspace programs – so it should always be OK to install the latest version of the headers.

Taken as a whole, installing a Capsicum kernel goes something like:

      % apt-cache search capsicum
      linux-firmware-image-3.19.0-capsicum+ - Linux kernel firmware, version 3.19.0-capsicum+
      linux-headers-3.19.0-capsicum+ - Linux kernel headers for version 3.19.0-capsicum+ on amd64
      linux-image-3.19.0-capsicum+ - Linux kernel, version 3.19.0-capsicum+
      % V=3.19.0-capsicum+
      % sudo apt-get install linux-image-$V linux-firmware-image-$V linux-headers-$V linux-libc-dev
      % sudo reboot
    

On rebooting, the Capsicum kernel will probably be entered by default, as it is likely to be a higher version than that shipped with Ubuntu by default. To see the list of available kernels, hold (right) shift during boot, then select "Advanced options for Ubuntu". A Capsicum kernel should be at the top of the list, with the original kernel (an older "-generic" kernel) further down. If there are any problems, boot into the original kernel to explore.

VMware Shared Folders

If the Capsicum kernel is installed within a VMware guest, the VMware vmhgfs kernel module will become unavailable after reboot. This means that shared folders (between the guest and host) will no longer be available.

      # sudo insmod vmhgfs
      insmod: ERROR: could not load module vmhgfs: No such file or directory

The normal way to fix this would be to reinstall the VMware tools; however, the kernel module code included in VMware has not been updated to match recent Linux kernels (3.19) and so does not build.

To patch the VMware kernel module so it works with a recent kernel, follow the instructions at the vmware-tools-patches GitHub repo (at your own risk).

Install the User Library

This should be as simple as sudo apt-get install libcaprights0 libcaprights-dev. Afterwards, the file /usr/include/sys/capsicum.h should exist, and man cap_rights_limit should show information about the Capsicum userspace API.

Optional: Run the Test Suite

Clone the Capsicum test suite into a suitable directory with git clone https://github.com/google/capsicum-test. Install the package dependencies with sudo apt-get install g++ libcap-dev libsctp-dev libsctp1 then move into the capsicum-test subdirectory and type make test

Install Capsicumized Versions of Applications

Various Capsicumized application packages are available at the repo; to see what's available, run:

% awk '$1 == "Package:" { print $2 }' /var/lib/apt/lists/pkg.capsicum-linux.org_*_Packages

Some particular Capsicumized applications are:

Checking Capsicum Status of an Application

There are a couple of ways of checking that an application is using Capsicum. Firstly, you can look for a run-time dependency on the Capsicum userspace library:

% ldd `which sshd`
	linux-vdso.so.1 =>  (0x00007ffff17c5000)
	libwrap.so.0 => /lib/x86_64-linux-gnu/libwrap.so.0 (0x00007fde51696000)
	libpam.so.0 => /lib/x86_64-linux-gnu/libpam.so.0 (0x00007fde51488000)
	libcaprights.so.0 => /usr/lib/x86_64-linux-gnu/libcaprights.so.0 (0x00007fde51283000)
	libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007fde51060000)
	libck-connector.so.0 => /usr/lib/x86_64-linux-gnu/libck-connector.so.0 (0x00007fde50e5c000)
	libdbus-1.so.3 => /lib/x86_64-linux-gnu/libdbus-1.so.3 (0x00007fde50c16000)
	libcrypto.so.1.0.0 => /lib/x86_64-linux-gnu/libcrypto.so.1.0.0 (0x00007fde5083c000)
	libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007fde50639000)
	libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fde5041f000)
	libcrypt.so.1 => /lib/x86_64-linux-gnu/libcrypt.so.1 (0x00007fde501e6000)
	libgssapi_krb5.so.2 => /usr/lib/x86_64-linux-gnu/libgssapi_krb5.so.2 (0x00007fde4ffa0000)
	libkrb5.so.3 => /usr/lib/x86_64-linux-gnu/libkrb5.so.3 (0x00007fde4fcd4000)
	libcom_err.so.2 => /lib/x86_64-linux-gnu/libcom_err.so.2 (0x00007fde4fad0000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fde4f70a000)
	libnsl.so.1 => /lib/x86_64-linux-gnu/libnsl.so.1 (0x00007fde4f4ef000)
	libaudit.so.1 => /lib/x86_64-linux-gnu/libaudit.so.1 (0x00007fde4f2cb000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fde4f0c7000)
	libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007fde4ee88000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fde51b85000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fde4ec6a000)
	librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fde4ea62000)
	libk5crypto.so.3 => /usr/lib/x86_64-linux-gnu/libk5crypto.so.3 (0x00007fde4e832000)
	libkrb5support.so.0 => /usr/lib/x86_64-linux-gnu/libkrb5support.so.0 (0x00007fde4e627000)
	libkeyutils.so.1 => /lib/x86_64-linux-gnu/libkeyutils.so.1 (0x00007fde4e423000)
	libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x00007fde4e207000)
    

Secondly, it is possible to examine the file descriptors of a running process to check for restricted rights. For example, while an ssh client is in the middle of logging in (i.e. has the password prompt up):

# pstree -A -p `pgrep sshd | head -1`
sshd(8071)---sshd(9479)---sshd(9480)
# more /proc/9480/fdinfo/*
::::::::::::::
/proc/9480/fdinfo/0
::::::::::::::
pos:	0
flags:	0100002
mnt_id:	18
rights:	0x200000000000000	0x400000000000000
 fcntls: 0x000000
::::::::::::::
/proc/9480/fdinfo/1
::::::::::::::
pos:	0
flags:	0100002
mnt_id:	18
rights:	0x200000000000000	0x400000000000000
 fcntls: 0x000000
::::::::::::::
/proc/9480/fdinfo/2
::::::::::::::
pos:	0
flags:	0100002
mnt_id:	18
rights:	0x200000000000000	0x400000000000000
 fcntls: 0x000000
::::::::::::::
/proc/9480/fdinfo/3
::::::::::::::
pos:	0
flags:	02004002
mnt_id:	8
::::::::::::::
/proc/9480/fdinfo/4
::::::::::::::
pos:	0
flags:	02000002
mnt_id:	8
rights:	0x200000000000003	0x400000000000000
 fcntls: 0x000000
::::::::::::::
/proc/9480/fdinfo/5
::::::::::::::
pos:	0
flags:	01
mnt_id:	9
::::::::::::::
/proc/9480/fdinfo/8
::::::::::::::
pos:	0
flags:	02000001
mnt_id:	9
rights:	0x200000000000002	0x400000000000000
 fcntls: 0x000000