Process hiding - hidepid capabilities of procfs

September 30th, 2013 by Philip Iezzi 3 min read
cover image

Five years ago I wrote about kernel based process hiding in Linux (see my old blog posts: Simple process hiding kernel patch, Process hiding Kernel patch for 2.6.24.x, RSBAC – Kernel based process hiding). It got time to continue the story and finally present you a real solution without the hassle of a self-compiled kernel.

How can I prevent users from seeing processes that do not belong to them?

In January 2012, Vasiliy Kulikov came up with a kernel patch that solved the problem nicely by adding a hidepid mount option for procfs. The patch landed in Linux kernel 3.3.

In the meantime, this patch luckily also landed in the 3.2 kernel of Debian Wheezy (see backport request in Debian bug report #669028). This feature has been also pushed back into the kernel of Red Hat Enterprise Linux 6.3 (see RHEL 6.3 Release Notes), and from there to CentOS 6.3 and Scientific Linux 6.3. Recently, this feature was even backported to the 2.6.18 kernel in RHEL 5.9.

As Proxmox VE currently runs on a RHEL based 2.6.32 kernel, it's also supported in my favorite OpenVZ/KVM virtualization platform. Great!

hidepid=0 (default) means the current behaviour - anybody may read all world-readable /proc/PID/* files.

hidepid=1 means users may not access any /proc/PID/ directories, but their own. Sensitive files like cmdline, io, sched*, status, wchan are now protected against other users. As permission checking done in proc_pid_permission() and files' permissions are left untouched, programs expecting specific files' permissions are not confused.

hidepid=2 means hidepid=1 plus all /proc/PID/ will be invisible to other users. It doesn't mean that it hides a fact whether a process exists (it can be learned by other means, e.g. by sending signals), but it hides process' euid and egid. It greatly compicates intruder's task of gathering info about running processes, whether some daemon runs with elevated privileges, whether other user runs some sensitive program, whether other users run any program at all, etc.

On a shared server I strongly recommend to enable the hidepid=2 procfs mount option. This can be done at runtime by remounting procfs:

$ mount | grep ^proc
proc on /proc type proc (rw,relatime)

$ mount -o remount,hidepid=2 /proc

$ mount | grep ^proc
proc on /proc type proc (rw,relatime,hidepid=2)

You may also add this mount option directly to /etc/fstab in order to make it persistent:

proc            /proc           proc    defaults,hidepid=2        0       0

A regular system user will then only see his own processes, e.g.:

testuser@web:~$ ps
  PID TTY          TIME CMD
17486 pts/0    00:00:00 bash
24806 pts/0    00:00:00 ps

This also works for other commands like pstree, top, htop,...

To get process hiding working inside a Proxmox VE container, simply remount procfs inside the VE, e.g. by the following init script ''/etc/init.d/system-hardening'':

#!/bin/bash

### BEGIN INIT INFO
# Provides:          system-hardening
# Required-Start:    $all
# Required-Stop:     $local_fs $remote_fs $syslog $named $network
# Should-Start:
# Should-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Run system-hardening startup actions
# Description:       Run system-hardening startup actions
### END INIT INFO

. /lib/lsb/init-functions

log_daemon_msg "Added proc mount option (hidepid=2)"
mount -o remount,hidepid=2 /proc
log_end_msg $?

Install the init script:

$ insserv system-hardening

links/credits to: