How to Inspect and Audit Linux Process Capabilities Using capsh and getpcaps

Traditionally, Linux access control operated on a binary security model: a process either executed as an unprivileged user (UID > 0) with restricted permissions, or executed as the all-powerful root user (UID 0) with unrestricted system access. Running system daemons—such as web servers binding to privileged ports, network sniffers capturing raw packets, or time-synchronisation services adjusting the hardware clock—traditionally required full root privileges, exposing systems to complete compromise if a daemon was hijacked. Linux Capabilities break the monolithic power of root into distinct, granular privileges. The libcap suite provides tools such as getpcaps and capsh, allowing systems administrators to inspect active process capabilities and test privilege boundaries safely.

Understanding Linux Capability Sets and Architecture

Instead of granting full administrative control, the Linux kernel divides root authority into roughly 40 distinct capability flags (such as CAP_NET_BIND_SERVICE, CAP_SYS_ADMIN, CAP_SYS_PTRACE, and CAP_CHOWN).

Every process maintains five separate capability sets:

  • Permitted (P): The limiting superset of capabilities that the thread may assume.
  • Effective (E): The capabilities currently active and evaluated by the kernel during permission checks.
  • Inheritable (I): Capabilities preserved across an execve() system call.
  • Bounding Set (B): A security ceiling that restricts which capabilities a process can ever obtain, even if executing a setuid binary.
  • Ambient (A): Capabilities preserved across unprivileged program executions without requiring file capabilities.

Installing the libcap-ng and libcap Utilities

To inspect and manipulate capabilities, install the libcap utilities package:

On Debian and Ubuntu

sudo apt update
sudo apt install libcap2-bin

On Fedora, RHEL, and AlmaLinux

sudo dnf install libcap

On Arch Linux

sudo pacman -S libcap

Auditing Process Capabilities with getpcaps

The getpcaps utility queries the kernel to display the active capability sets of any running process by Process ID (PID).

Step 1: Inspecting a Standard Daemon

Locate the PID of an active network daemon (e.g. systemd-resolved, NTP, or Nginx) using pgrep:

pgrep systemd-resolve

Assume the returned PID is 842. Query its capability sets:

getpcaps 842

Sample output:

842: cap_net_bind_service,cap_net_raw+ep

Notice that systemd-resolved runs with only CAP_NET_BIND_SERVICE (to bind to port 53) and CAP_NET_RAW (to construct DNS packets). It possesses no filesystem alteration or kernel manipulation privileges, drastically minimizing attack surface.

Step 2: Inspecting File Capabilities with getcap

To inspect binaries configured with standalone file capabilities rather than setuid root:

getcap /usr/bin/ping

Output typically confirms /usr/bin/ping = cap_net_raw+ep, enabling ping to send ICMP echo packets without running as full root.

Decoding Low-Level Status Flags via /proc

When investigating processes without getpcaps, inspect the kernel process status directly:

grep Cap /proc/$$/status

Output displays bitmap masks:

CapInh: 0000000000000000
CapPrm: 0000003fffffffff
CapEff: 0000003fffffffff
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000

To decode these hexadecimal masks into human-readable capability names, use capsh --decode:

capsh --decode=0000003fffffffff

Testing Privilege Dropping with the capsh Shell Wrapper

The Capability Shell wrapper (capsh) provides an isolated test environment to launch processes with deliberately restricted capability sets, verifying whether applications survive privilege dropping.

Step 1: Spawning a Shell with Dropped Capabilities

To launch a root shell that has dropped CAP_SYS_ADMIN and CAP_NET_ADMIN from its bounding set:

sudo capsh --drop=cap_sys_admin,cap_net_admin --

Step 2: Testing Permission Boundaries

  1. Inside the restricted shell, verify that root commands are still available (such as reading /etc/shadow).
  2. Now attempt an action requiring CAP_SYS_ADMIN, such as mounting a loop device:
    mount -t tmpfs none /mnt
  3. The kernel immediately blocks the action with mount: /mnt: permission denied, proving that the capability ceiling successfully curtailed root authority.
  4. Type exit to terminate the test shell.

Auditing and enforcing Linux capabilities using getpcaps and capsh transforms system hardening from blunt root access into precise, defense-in-depth security architectures.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.