Home / Alt manpages / proc_pid_root(5)

  • proc_pid_root(5)
  • File format
  • linux

Use /proc/pid/root to Inspect a Process's Filesystem View

You will finish with a safe way to inspect the root directory as seen by a running process, including the process's mount namespace. The key path is /proc/PID/root. It looks like a symbolic link, but the kernel resolves it using that process's filesystem view rather than simply substituting the host's /.

Allow about ten minutes for the basic checks. You need a Linux shell and a running process to inspect. The examples use Linux man-pages 6.7 from package manpages version 6.7-2. They do not change files, mounts or process state. The optional namespace lab needs a kernel that permits the requested namespace operation and is not required for normal inspection.

1. Check the local documentation and your own root

Read the installed manual first. This is an ordinary, unprivileged command:

$ man 5 proc_pid_root

Confirm the package version and resolve your own link:

$ dpkg-query -W -f='${Package} ${Version}\n' manpages
manpages 6.7-2
$ readlink /proc/self/root
/
$ ls -ld /proc/self/root
lrwxrwxrwx 1 your-user your-group 0 ... /proc/self/root -> /

The exact owner, group, timestamp and link display vary. The useful result is that readlink reports the root visible to the current shell. self is a convenient procfs alias for the process making the lookup.

Checkpoint

If /proc is not mounted, or /proc/self/root is missing, stop here. This guide cannot work until procfs is available.

2. Choose a live process and record its PID

Use a process you are allowed to inspect. A short-lived command is easy to miss, so start a harmless sleep in the current shell:

$ sleep 300 &
[1] 27123
$ PID=$!
$ printf 'inspecting PID %s\n' "$PID"
inspecting PID 27123

Your shell will print a different PID. Keep the value in PID for the rest of the session. Check that it is still present without changing it:

$ test -d "/proc/$PID" && echo 'process is running'
process is running

Do not assume that a PID remains assigned to the same process. If a command reports that the path disappeared, reread the PID and repeat the check. Never use a stale PID for an automated diagnostic.

3. Inspect the target's root and ordinary paths

Read the link and list a directory through it:

$ readlink "/proc/$PID/root"
/
$ ls -ld "/proc/$PID/root" "/proc/$PID/root/etc"
lrwxrwxrwx 1 ... /proc/27123/root -> /
drwxr-xr-x 1 root root ... /proc/27123/root/etc

For a process in the host's normal root and mount namespace, this resembles the paths you see directly. That is not a guarantee. A process can have a different per-process root from chroot(2), a different mount namespace, or mounts that are private to it.

The procfs entry is therefore useful for examining the process's view. For example, compare a directory count without following a shell variable into an untrusted command:

$ find "/proc/$PID/root/etc" -mindepth 1 -maxdepth 1 -print | wc -l
309

The count is host-specific. It only establishes what this lookup returned at that moment. A process may exit or mounts may change while you are examining them.

4. Understand the namespace difference

To make the difference visible, the manual's example starts a shell in new user and mount namespaces, mounts an empty tmpfs over /etc, and then reads that shell's PID from another namespace:

$ unshare -Urnm
sh1# mount -t tmpfs tmpfs /etc
sh1# echo $$
27123

From a second shell with suitable access, the corresponding lookup can show the private mount:

$ ls /etc | wc -l
309
$ ls /proc/27123/root/etc | wc -l
0

Do not treat those numbers as expected output on every host. The first shell may be denied permission to create the user namespace, the mount may be blocked by policy, and the second shell may not be allowed to inspect the target. A failure such as unshare: ... uid_map: Operation not permitted means the lab is unavailable; it does not invalidate the ordinary /proc/PID/root checks. Do not weaken system policy merely to run this demonstration.

Mounting over /etc in a correctly isolated namespace does not alter the host's mount table. End the lab with exit. If you run a namespace experiment with a different command or privileges, verify its isolation before creating mounts.

Access to dereference or read this procfs link is subject to a ptrace access check using filesystem credentials. A process owner is not automatically allowed to inspect every other process. If readlink "/proc/$PID/root" fails with Permission denied, first check that the PID is correct and that the target is still running. Use elevated privileges only when your system policy explicitly permits that diagnostic:

$ sudo readlink "/proc/$PID/root"
/

Security boundary

sudo changes who performs the lookup. It does not make a missing process, an inaccessible namespace or a terminated thread reappear. Avoid putting untrusted PID values into scripts without validating that they are decimal PIDs and still refer to the intended process.

There is a less obvious failure for multithreaded programs. If the main thread has already terminated, the contents of /proc/PID/root may no longer be available even while other threads remain. Record the failure and inspect the process earlier, or identify a still-live process leader. Do not infer that the target's filesystem root changed merely from this error.

6. Stop the temporary test process

The example started a sleep process, so clean it up after inspection:

$ kill "$PID"
$ wait "$PID" 2>/dev/null || true

This sends the normal termination signal to the process you started. Do not substitute a PID copied from an unrelated command. If the process has already exited, there is nothing to undo.

Done means

  • You confirmed that procfs and /proc/self/root are available.
  • You inspected a live, deliberately selected PID and checked it had not disappeared.
  • You used /proc/PID/root to examine the process's filesystem view.
  • You know that chroot, mount namespaces and per-process mounts can change what the path exposes.
  • You can distinguish a permission failure, a stale PID and a terminated multithreaded process leader.
  • You stopped the temporary test process without changing persistent configuration.