Inspect /proc Safely and Restrict Process Visibility with hidepid
You will use /proc to inspect your own process, read kernel settings, and understand the hidepid mount option before changing process visibility for other users. The examples match the installed proc(5) from Linux man-pages 6.7, on a 6.8.0-139-generic kernel. Allow about fifteen minutes. Most steps are unprivileged; the mount test needs root and changes the current mount namespace.
The route
Jump straight to the step you need, or tick off Done means at the end.
- 1. Confirm the proc filesystem and mount options
- 2. Read process data through /proc/self
- 3. Handle null-separated proc files correctly
- 4. Inspect a sysctl pseudo-file before changing anything
- 5. Understand hidepid before testing it
- 6. Test hidepid in a controlled mount namespace
- 7. Diagnose the common traps
This guide is deliberately about inspection and a reversible test. It does not edit boot configuration, create a permanent fstab entry, or grant broad access through sudo.
1. Confirm the proc filesystem and mount options
Start with read-only checks. findmnt shows where proc is mounted and which options are active:
$ findmnt --target /proc --output TARGET,FSTYPE,OPTIONS
TARGET FSTYPE OPTIONS
/proc proc rw,nosuid,nodev,noexec,relatime
$ ls -ld /proc/self /proc/thread-self
lrwxrwxrwx ... /proc/self -> ...
lrwxrwxrwx ... /proc/thread-self -> ...
The exact option list and link targets vary. The useful facts are that the filesystem type is proc and that /proc/self is a magic link to the calling process's directory. /proc/thread-self resolves to the calling thread's directory, which matters in multithreaded programs.
Checkpoint: if findmnt reports no target, do not create a second mount just to make the examples work. Check the host's namespace and container configuration first.
2. Read process data through /proc/self
Use /proc/self instead of guessing your shell's process ID. This avoids a race in which a stored PID belongs to a different process by the time you read it:
$ sed -n '1,12p' /proc/self/status
Name: sed
Umask: 0022
State: R (running)
Tgid: ...
Ngid: 0
Pid: ...
PPid: ...
Field order and values are kernel-dependent, so do not parse a fixed line number in a long-lived script. Select a named field when you need one:
$ awk -F: '$1 == "Name" || $1 == "Pid" || $1 == "Uid" {print}' /proc/self/status
Name: awk
Pid: ...
Uid: ...
Notice that the command reading the file is the process represented by /proc/self. In the first example that is sed; in the second it is awk. This is expected and is a common source of misleading tests.
3. Handle null-separated proc files correctly
Some proc files, including command-line and environment data, use null bytes between fields. A normal terminal display can make that look like one damaged line. Convert nulls to newlines for inspection, without writing back to the proc file:
$ tr '\000' '\n' < /proc/self/cmdline
tr
\000\000
$ tr '\000' '\n' < /proc/self/environ | sed -n '1,5p'
SHELL=/bin/bash
...
The command name and arguments are process data, not a stable configuration interface. Environment values can contain secrets, so avoid copying this output into logs or support tickets. The input redirection is read-only; the displayed \000 is a shell representation of a null byte, not text you should write to /proc.
4. Inspect a sysctl pseudo-file before changing anything
Some files below /proc/sys expose kernel variables, and some are writable. Read one first and record its current value:
$ printf 'hostname: '
$ cat /proc/sys/kernel/hostname
hostname: server.dixon.cx
Reading does not need elevated privileges. Do not assume every file under /proc/sys is writable or that a value has the same meaning on another kernel. If you need to change a sysctl, use the documented setting and an explicit rollback value. A write can affect the running system immediately and may not survive a reboot.
Warning: this guide does not write a sysctl. Do not test with echo VALUE > /proc/sys/... on a production host unless you have identified the setting, its effect, and the recovery value.
5. Understand hidepid before testing it
hidepid controls access to /proc/PID directories. The default, hidepid=0, keeps the traditional visibility. hidepid=1 leaves process directories visible but protects files and subdirectories belonging to other users. hidepid=2 also hides those other users' process directories when /proc is listed.
The distinction is useful: hidepid=2 makes process discovery harder, but it does not make a process unknowable. The manual specifically notes that other mechanisms, such as probing a PID with kill -0, can still reveal that a PID exists. Treat this as reduced local information exposure, not a complete process-isolation boundary.
A group can be named with gid=GROUP. Members of that group receive access as though hidepid=0. The manual recommends this targeted exception instead of putting non-root users in sudoers.
6. Test hidepid in a controlled mount namespace
Changing the host's proc mount can break monitoring and process-management tools. Prefer a disposable mount namespace if your host permits it. This command requires root and changes only the namespace created for the shell:
$ sudo unshare --mount --fork sh
# mount --make-rprivate /
# mount -o remount,hidepid=2 /proc
# findmnt --target /proc --output TARGET,FSTYPE,OPTIONS
TARGET FSTYPE OPTIONS
/proc proc rw,nosuid,nodev,noexec,relatime,hidepid=2
# ls /proc | head
1
self
thread-self
# exit
The exact process list depends on the namespace and kernel. The mount --make-rprivate / step prevents mount events from propagating back to the host. The second mount command remounts the proc instance already visible inside that namespace; it is not a permanent configuration change.
Before running this, make sure unshare is available and that you understand the host's container and namespace policy. If unshare is refused, stop there. Do not work around the restriction by remounting the host's /proc as root.
Checkpoint: after exit, verify that the original mount is unchanged:
$ findmnt --target /proc --output TARGET,FSTYPE,OPTIONS
TARGET FSTYPE OPTIONS
/proc proc rw,nosuid,nodev,noexec,relatime
7. Diagnose the common traps
- If
/proc/selfappears to describe the wrong command, remember that it follows the process doing the read. Use a small helper command and interpret its output accordingly. - If another user's process files become unreadable after applying
hidepid=1, that is the intended result. Do not grantsudocasually; consider the dedicatedgidexception and its membership instead. - If process directories disappear under
hidepid=2, tools that enumerate/procmay show incomplete data. Test monitoring, service supervision and diagnostics before considering a persistent deployment. - If a proc file contains unreadable separators, check the manual's null-byte note and transform a copy of the output for display. Never assume a text line is the storage format.
Done means
- You confirmed the active proc mount with
findmnt. - You used
/proc/selfwithout relying on a stale PID. - You displayed null-separated data safely and kept environment values private.
- You distinguished
hidepid=1fromhidepid=2and understood the limits. - You tested a remount in a private namespace, or recorded why the host policy refused it.
- The host's original proc mount is unchanged after the test.