CIS 458 Lab 4: Capabilities in Linux

This lab assignment should be done alone. While you may discuss with other students, your work should be your own.

Objective: The objective of this lab is for students to gain a better understanding of capabilities though first-hand experiences with the capability mechanism in Linux.

Grading: Each question below is worth 1 point, except for question 5, which is worth 5 points.

This lab has been modified by Andrew Kalafut from the original "Linux Capibility Exploration Lab" written by Wenliang Du of Syracuse University. Copyright 2013 Andrew Kalafut. Copyright 2006 - 2011 Wenliang Du, Syracuse University. The development of the original document is/was funded by three grants from the US National Science Foundation: Awards No. 0231122 and 0618680 from TUES/CCLI and Award No. 1017771 from Trustworthy Computing. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation. A copyof the license can be found at

Lab Setup

This lab should be done on the SEED project VMWare images available on the EOS computers. Please do all steps in the SEED VM. Pay careful attention to which steps to run as root and which as a normal user.


Capability features are provided by the library libcap. A few useful commands also come with this library:

In operating systems, there are many privileged operations that can only be conducted by privileged users. Examples of privilegd operations include configuring network interface card, backing up all the user files, shutting down the computers, etc. Without capabilities, these operations can only be carried out by superusers, who often have many more privileges than what are needed for the intended tasks. Therefore, letting superusers to conduct these privileged operations is a violation of the Least-Privilege Principle.

Privileged operations are very necessary in operating systems. All Set-UID programs invole privileged operations that cannot be performed by normal users. To allow normal users to run these programs, Set-UID programs turn normal users into powerful users (e.g. root) temporarily, even though that the involved privileged operations do not need all the power. This is dangerous: if the program is compromised, adversaries might get the root privilege.

Capabilities divide the powerful root privilege into a set of less powerful privileges. Each of these privileges is called a capability. With capabilities, we do not need to be a superuser to conduct privileged operations. All we need is to have the capabilities that are needed for the privileged operations. Therefore, even if a privileged program is compromised, adversaries can only get limited power. This way, risk of privileged program can be lowered quite significantly. Capabilities have been implemented in Linux for quite some time, but they could only be assigned to processes. Since kernel version 2.6.24, capabilities can be assigned to files (i.e., programs) and turn those programs into privileged programs. When a privileged program is executed, the running process will carry those capabilities that are assigned to the program. In some sense, this is similar to the Set-UID files, but the major difference is the amount of privileged carried by the running processes.

Part 1: Exploring Capabilities

In a capability system, when a program is executed, its corresponding process is initialized with a list of capabilities (tokens). When the process tries to access an object, the operating system check the process’ capabilities, and decides whether to grant the access or not.

First, login as a normal user, and run the following command:

The program should run successfully. If you look at the file attributes of the program /bin/ping, you will find out that ping is actually a Set-UID program with the owner being root, i.e., when you execute ping, your effective user id becomes root, and the running process is very powerful. If there are vulnerabilities in ping, the entire system can be compromised. The question is whether we can remove these privileges from ping.

Turn /bin/ping into a non-Set-UID program. This can be done via the following command as root (you can log in as root by running su root):

  chmod u-s /bin/ping

Now, run ping again (as a normal user), and see what happens. Interestingly, the command will not work. This is because ping needs to open a RAW socket. Assign the cap net raw capability to ping with the following command (as root):

  setcap cap_net_raw=ep /bin/ping
The ping command should work again.
  1. Explain why this command made ping work again.
  2. Why did ping work without the capability before the Set-UID bit was removed?

Several other programs run as Set-UID as well. You can find them with the command find /usr/bin /bin -perm -4000 Choose one of these and remove the Set-UID bit using chmod.

  1. What program did you choose. What does the program normally do? What happens now that you removed the Set-UID bit?

A short description of each capability is available in /usr/include/linux/capablity.h. Take a look at this file and determine which capabilities the program you chose should need.

  1. What capability needs to be added to this program to make it work again? (note: there may be more than one) In your own words (not repeating the descriptions given in capability.h), why is this capability needed for this program?

Part 2: Adjusting Privileges

Capabilities have another advantage: it is convenient to dynamically adjust the amount of privileges a process has, which is essential for achieve the principle of least privilege. For example, when a privilege is no longer needed in a process, we should allow the process to permanently remove the capabilities relevant to this privilege. Therefore, even if the process is compromised, attackers will not be able to gain these deleted capabilities. Adjusting privileges can be achieved using the following capability management operations:

Without capabilities, a privileged Set-UID program can also delete/disable/enable its own privileged. This is done via the setuid() and seteuid() system calls; namely, a process can change its effective user id during the run time. The granularity is quite coarse using these system calls, because you can either be the privileged users (e.g. root) or a non-privileged users. With capabilities, the privileges can be adjusted in a much finer fashion, because each capability can be independently adjusted.

To support dynamic capability adjustment, Linux uses a mechanism similar to the Set-UID mechanism, i.e., a process carries three capability sets: permitted (P), inheritable (I), and effective (E). The permitted set consists of the capabilities that the process is permitted to use; however, this set of capabilities might not be active. The effective set consists of those capabilities that the process can currently use (this is like the effective user uid in the Set-UID mechanism). The effective set must always be a subset of the permitted set. The process can change the contents of the effective set at any time as long as the effective set does not exceed the permitted set. The inheritable set is used only for calculating the new capability sets after exec(), i.e., which capabilities can be inherited by the children processes.

Download and compile use_cap.c. The program can be compiled by running gcc -o use_cap use_cap.c /lib/libcap.a. Read the program, grant it the cap_dac_read_search capabilty (you will need to be root to do this), and run it as a normal user (not root).

  1. Which attempts to open the file succeeded or failed? Explain why for each (5 points).
  2. After a program disables a capaibility A, it is compromised by an attack that causes the program to run code specified by the attacker. The attacker injects malicious code into the program's stack space and starts to run it. Can the attacker use capability A? What if the capability was dropped (deleted) instead of disabled?