RFC: User capabilities

This is a proposal to extend the Linux capabilities framework to include capabilities that are not traditionally part of root's super powers.

Background

The capabilities framework in the Linux kernel has split the monolithic 'superuser' powers of the root user into various discrete capabilities. These capabilities are implemented in such a way that

  • by default, the root user has all capabilities (FULL set) and a non-root user has none (EMPTY set)
  • a process running as the root user can drop capabilities from its permitted set, effectively giving up a certain power until the end of its lifetime
  • a process running as non-root can inherit or acquire a capability, allowing it to perform a specific superuser task in addition to its normal non-root privileges.

There exist certain actions that can be performed by processes running as non-root which few programs actually need, such as opening server sockets, calling ptrace() on other processes running under the same uid, or creating memory mappings that are both writable/dirty and executable. All of these examples, and others, are abilities that are often abused by malware, and restricting these can significantly enhance userland security.

Various projects aim to address these issues, but usually it is done by introducing both a kernel feature, and some policy (and tunables) to control the feature. For example, the way Yama handles ptrace, or PaX MPROTECT handles executable and writable mappings is very pervasive and likely to cause breakage.

Proposal

Instead, I propose to introduce 'user capabilities' into the kernel. By defining capabilities for actions that up until now did not require any special permissions at all, and replacing the default EMPTY set of non-root capabilities with the union of those new capabilities (e.g., CAP_USR_TCP_LISTEN | CAP_USR_PTRACE | CAP_USR_WX_MAPPINGS), we can leave it up to the userland to drop any or all of them if they are deemed unnecessary. For instance, the ability to create writable+executable mappings can be dropped in the loader, unless some program header indicates otherwise. Such an indication could be given, for instance, by the Java JRE binary which could then drop the capability itself after creating its rwx JIT heap.

In fact, it would then be entirely up to the userland in which cases (if at all) to use this feature, making it low impact and highly maintainable from kernel pov.

Proposed initial set of user capabilities:

  • CAP_USR_TCP_LISTEN, required to create TCP server sockets;
  • CAP_USR_PTRACE, required to call ptrace() on other processes, even ones running under the same uid;
  • CAP_USR_WX_MAPPINGS, required to create mappings that are both writable and executable, to enable execute permissions on mappings that are already writable or dirty and to enable write permissions on executable mappings;
  • CAP_USR_FORK_EXEC, required to spawn new processes or replace the running program in the current process.

ardbiesheuvel/UserCapabilities (last modified 2013-03-26 07:58:54)