Thursday, May 17, 2012

Lazyweb question: How to avoid leaking process info?

Dear Lazyweb,

is there a simple way to block some users who login with SSH to read /proc/<pid>/cmdline of processes they don't own? Or better yet: don't see these pids at all?

I know that there are PID namespaces, but they seem to require a special PID 1. Seems hard to get for a simple SSH login. (I wouldn't mind changing a user's shell. But brittle shell startup scripts wouldn't cut it.) systemd-nspawn wants to boot a full Linux distribution in a container and even then I'd be unsure how to wire it up so that it cannot be skipped. I wouldn't mind a read-only bind mount of the outermost Linux installation into a chroot environment, as long as the parent SSH process can get the user jailed into it securely. (No need for someone to be root in the chroot.)

I know that there are RBAC frameworks, but they're cumbersome to use. I don't need file labelling or path-based access control, as I do trust the Linux file permissions for this. I think SMACK wouldn't help here, AppArmor isn't really useable in Debian testing and TOMOYO is a tad crazy to use with its domain transitions through process invocations.

I bet that grsecurity would have something for me up its sleeve. But it's not in a Debian kernel. Even though I know how to compile my own kernel I'd only do that if everything else fails.

Thanks in advance for your help.

UPDATE: That was quick, thanks to everyone who participated! Vasiliy Kulikov came up with a kernel patch to my problem (a hidepid mount option for procfs) that landed in 3.3. I tested it with the kernel in experimental and it works just fine and as expected. With hidepid set to 1, it will still leak the process count and their euids and egids. With hidepid set to 2, you only see your own processes, unless you're root. For ps there's no visible distinction between the two. So to test it you can just invoke this as root on a host running 3.3+:
mount -o remount,hidepid=1 /proc
There's even a backport request in the Debian BTS to get the feature into the wheezy kernel (3.2).

11 comments:

  1. If you don't mind users not seeing their own processes either, you could mount /proc with root-only permissions (0500) or with permissions only for a trusted group (0550 root:adm or similar).

    ReplyDelete
    Replies
    1. Does that really work? According to this LWN article it's not part of the VFS layer to mount filesystems with overriding uid/gid/mode settings. I know that NTFS and vfat support it, but a trivial experiment doesn't work for me for /proc. Does it work for you?

      Delete
    2. ~$ ls -ld /proc
      dr-xr-xr-x 144 root root 0 May 14 21:33 /proc
      ~$ sudo chmod 0500 /proc
      ~$ ls -ld /proc
      dr-x------ 145 root root 0 May 14 21:33 /proc
      ~$ ps auxf
      Cannot find /proc/version - is /proc mounted?

      Delete
  2. See http://unix.stackexchange.com/a/34224/15241 and other answers there.

    ReplyDelete
  3. Inspired by setuid-sandbox (which you might wanna look at): There's a flag to the clone() syscall to make the child go in new PID-namespace. I don't think it requires any caps. So make a small wrapper-shell that executes the user's shell this way.

    ReplyDelete
  4. You cna use the hidepid mount option for the /proc filesystem. Quoting http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob;f=Documentation/filesystems/proc.txt , §4.1 "Mount options":

    hidepid=2 means hidepid=1 plus all /proc// will be fully invisible to other users. It doesn't mean that it hides a fact whether a process with a specific pid value exists (it can be learned by other means, e.g. by "kill -0 $PID"), but it hides process' uid and gid, which may be learned by stat()'ing /proc// otherwise. It greatly complicates an intruder's task of gathering information 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.

    ReplyDelete
    Replies
    1. You can also pass a gid=NNN option, which will limit /proc to that group ID. Probably safer than chmod.

      Delete
  5. OpenVZ? Squeeze has an -openvz kernel flavour but unfortunately Wheezy's kernel won't have it.

    Each container gets its own process namespace, with a fully isolated /proc and /sys (and virtual network interfaces, and a filesystem which is chrooted in some dir on the host system). Only the host is able to see all processes. Ability to limit resources like memory, sockets, inodes and/or filesystem quota per container might be a bonus.

    ReplyDelete
  6. For the benefit of readers making their own kernels: You also need this patch

    https://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commit;h=a2ef990ab5a6705a356d146dd773a3b359787497

    ReplyDelete
  7. So are you (or anyone) going to test the result of cherry-picking the commits listed in http://bugs.debian.org/669028 into the Debian kernel package?

    Instructions for rebuilding:
    http://kernel-handbook.alioth.debian.org/ch-common-tasks.html#s-common-official

    ReplyDelete
    Replies
    1. Apparently someone did and it just got uploaded to sid.

      Delete