Friday, November 09, 2007

Limiting Process Privileges Should Be Easier

I was reading DJB's retrospective on 10 years of qmail security and while I'll comment on a few of his thoughts in a separate post, one thing that struck me was his discussion of how to create a relatively effective process sandbox for a process:

  • Prohibit new files, new sockets, etc., by setting the current and maximum RLIMIT_NOFILE limits to 0.
  • Prohibit filesystem access: chdir and chroot to an empty directory.
  • Choose a uid dedicated to this process ID. This can be as simple as adding the process ID to a base uid, as long as other system-administration tools stay away from the same uid range.
  • Ensure that nothing is running under the uid: fork a child to run setuid(targetuid), kill(-1,SIGKILL), and _exit(0), and then check that the child exited normally.
  • Prohibit kill(), ptrace(), etc., by setting gid and uid to the target uid.
  • Prohibit fork(), by setting the current and maximum RLIMIT_NPROC limits to 0.
  • Set the desired limits on memory allocation and other resource allocation.
  • Run the rest of the program.

If doing all of the above steps seems like a bit much, then perhaps what you're sensing is that the architectural model that makes it hard for a process to drop privs, restrict what it can do, etc. is simply wrong in most operating systems.

What strikes me about the above example is that it ought to be a lot easier for a developer/administrator to define the policy for a given process and its run environment, without having to know this much arcana about exactly how to do it.

Luckily, there are a few OS-supplied solutions to the problem that while not perfect and still tricky to implement, are at least a step in the right direction.

Solaris
Windows Server 2008
  • Microsoft has introduced service hardening and reduced privileges in Server-2008.
  • Based on what I can tell their new wizard and SCM in general are structured more around least privilege than some of the other operating systems. At least from an ease-of-use standpoint.
Linux
  • On Linux we have several options.
    • SELinux
    • AppArmor
  • I haven't looked extensively at either of them yet but I'll try to look into whether their policy model is better/worse than the options above.
MacOS
  • Leopard introduces a new process sandboxing mechanism. Unfortunately the details are a bit sketchy. The Matasano guys have a writeup of it, but I haven't seen any details on the exact mechanisms and/or configuration.

No comments: