Home / Alt manpages / captree(8)

  • captree(8)
  • Admin command
  • linux

Read Process Capability Trees Safely with captree

You will finish with a read-only workflow for inspecting the Linux capabilities attached to a process tree, including how to limit traversal and how to distinguish an empty display from missing information. The examples follow captree(8) as installed with libcap2-bin version 1:2.66-5ubuntu2.4.

Allow about ten minutes. You need a shell and a libcap build that includes the captree executable. The command only inspects process state in this workflow, so elevated privileges are not a normal prerequisite. Processes owned by another account may still be less visible or may change while you inspect them.

1. Check that the executable is really installed

Start by checking the command and the package version. This is an ordinary, read-only check:

$ command -v captree
$ dpkg-query -W -f='${Package} ${Version}\n' libcap2-bin
libcap2-bin 1:2.66-5ubuntu2.4

The first command should print the path to an executable before you continue. On the reference machine used for this guide, it prints nothing: the package contains the manual page but dpkg -L libcap2-bin lists capsh, getcap, getpcaps and setcap, not captree. That is a packaging fact, not a reason to pretend that the command ran. If your host has the same layout, stop here and obtain a matching libcap build through your normal package or build process. Do not replace system files by hand.

Checkpoint: this must succeed before any later example can work:

$ captree --help
captree [OPTIONS] [(pid|glob-name) ...]

The exact help text can differ between Go runtime versions. The installed manual records status 0 for modern runtimes and status 2 for older runtimes when --help is used.

2. Inspect the default target

With no target argument, captree uses PID 1. Run it without sudo first:

$ captree
host-specific capability tree for PID 1

The real output is host-specific. Capabilities use the quoted text form understood by cap_from_text(3). An IAB tuple, when useful, appears in square brackets using the cap_iab(3) text form. Do not copy a capability list from one machine to another and treat it as a baseline. The process, kernel, service manager and launch configuration all affect it.

To make the target explicit, pass a numeric PID:

$ TARGET_PID=1234
$ captree "$TARGET_PID"
capability tree rooted at PID 1234, if it exists

Replace 1234 with a PID that exists on your host. Discover one without changing state if needed:

$ pgrep -xo systemd
1

A supplied target that cannot be found gives exit status 1. Check the status immediately if a script depends on the result:

$ captree "$TARGET_PID" > /tmp/captree.txt
$ status=$?
$ printf 'captree status: %s\n' "$status"
captree status: 0

Do not interpret status 0 as proof that every process in a changing tree was examined without interruption. It means captree completed according to its documented target lookup and traversal.

3. View all kernel-known processes carefully

PID 0 is special to captree: it requests all processes known to the kernel. This can produce much more output than the default, so write it to a new file if you need to review it:

$ captree 0 > /tmp/captree-all.txt
$ printf 'captree status: %s\n' "$?"
captree status: 0

This creates or truncates /tmp/captree-all.txt. Do not use a valuable report path without checking it first. If you want to keep an existing report, choose a new name or use a shell redirection target that you have deliberately prepared. The command itself does not modify processes, capabilities or service configuration.

A PID value is not the only target form. The manual also permits a glob-name value, so a process name pattern can select matching processes. Use a quoted pattern to prevent the shell from expanding it before captree sees it:

$ captree 'sshd*'
capability trees for matching process names, if any

Keep the pattern narrow. A broad pattern can select more processes than intended, while a name can change between discovery and inspection. If you need a stable audit target, prefer a numeric PID and record when it was checked.

4. Limit tree depth for a focused check

Use --depth=n to limit how far captree descends from the selected process. The default is 0, which means unlimited depth, not zero displayed levels:

$ captree --depth=1 "$TARGET_PID"
the target and its first level of descendants

Depth is useful when PID 1 or PID 0 produces a long tree. Start with a small value, then increase it when you need more context. Options must come before the list of PID or name targets.

For a repeatable text report, redirect standard output and check the status before trusting the file:

$ captree --depth=2 "$TARGET_PID" > /tmp/captree-depth-2.txt
$ test "$?" -eq 0 && wc -l /tmp/captree-depth-2.txt

5. Show empty and redundant capability fields

By default, captree omits the IAB tuple when its inheritable and ambient components are empty or redundant with the regular capability text. That is a presentation choice, not evidence that the process has no capability state. Add --verbose when an empty field is relevant to your investigation:

$ captree --verbose "$TARGET_PID"
capability sets and IAB tuples, including empty or redundant values

Compare like with like. A report made with --verbose has more fields than one made without it, so record the option with any saved evidence. The capability text is descriptive; changing capabilities requires other tools and appropriate security review.

6. Control colour and diagnose failures

When standard output is a terminal, targeted PIDs are coloured red by default. Piping output normally suppresses colour, but use --colour=false when a plain report is required:

$ captree --colour=false --depth=1 "$TARGET_PID" > /tmp/captree-plain.txt

The manual also accepts a US spelling variant for the same option. Keep that literal spelling in scripts only when you need compatibility with it:

$ captree --color=false --depth=1 "$TARGET_PID" > /tmp/captree-plain.txt

This option only changes presentation. It does not hide capabilities or alter process state.

If you see status 1, check that the PID or name still exists. If you see status 2, inspect option spelling and placement. For a safe target check:

$ test -d "/proc/$TARGET_PID" && echo 'PID still exists'
PID still exists

A process can exit after that test, so it is only a diagnostic, not a lock. Do not use sudo as the first response to a lookup failure. It cannot make a nonexistent target reappear, and the documented command does not require a state-changing privileged operation.

Done means

  • captree is present and its package or build provenance is known.
  • You can inspect PID 1, an explicit PID, a name glob or all kernel-known processes.
  • You use --depth to control large trees and understand that depth 0 means unlimited.
  • You use --verbose when omitted empty or redundant IAB fields matter.
  • Saved reports record the target, options, time and exit status.
  • No process, capability, service or persistent configuration was changed.