seccomp: Add self-test for dual seccomp mode

Test that seccomp-strict mode and seccomp-bpf mode can
be combined.

Signed-off-by: David Drysdale <drysdale@google.com>
seccomp: introduce writer locking

Normally, task_struck.seccomp.filter is only ever read or modified by
the task that owns it (current). This property aids in fast access
during system call filtering as read access is lockless.

Updating the pointer from another task, however, opens up race
conditions. To allow cross-task filter pointer updates, writes to the
seccomp fields are now protected via a spinlock.  Read access remains
lockless because pointer updates themselves are atomic.  However, writes
(or cloning) often entail additional checking (like maximum instruction
counts) which require locking to perform safely.

In the case of cloning threads, the child is invisible to the system
until it enters the task list. To make sure a child can't be cloned
from a thread and left in a prior state, seccomp duplication is moved
under the tasklist_lock. Then parent and child are certain have the same
seccomp state when they exit the lock.

Based on patches by Will Drewry.

Signed-off-by: Kees Cook <keescook@chromium.org>
seccomp: create locked helper for setting mode

For multiple mode-setting callers, we will need a helper to perform the
sanity-checking and finalization logic while the seccomp lock is held.

Signed-off-by: Kees Cook <keescook@chromium.org>
seccomp: move no_new_privs into seccomp

Since seccomp transitions between threads requires updates to the
no_new_privs flag to be atomic, this creates accessors for it. In the
case of seccomp being built into the kernel, the flag is moved it into
seccomp struct where it can be updated safely.

Signed-off-by: Kees Cook <keescook@chromium.org>
seccomp: add PR_SECCOMP_EXT and SECCOMP_EXT_ACT_FILTER

This change adds a new seccomp "extension" framework for more complex
filter actions and option setting. The need for the added prctl() is
due to the lack of reserved arguments in PR_SET_SECCOMP (much existing
code already calls prctl without initializing trailing arguments).

When prctl(PR_SECCOMP_EXT, SECCOMP_EXT_ACT_FILTER, flags, filter) is
called, it will be the same as prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER,
filter), when flags is 0. This will allow for additional flags being
set on the filter in the future.

Signed-off-by: Kees Cook <keescook@chromium.org>
seccomp: add SECCOMP_EXT_ACT_TSYNC and SECCOMP_FILTER_TSYNC

Applying restrictive seccomp filter programs to large or diverse
codebases often requires handling threads which may be started early in
the process lifetime (e.g., by code that is linked in). While it is
possible to apply permissive programs prior to process start up, it is
difficult to further restrict the kernel ABI to those threads after that
point.

This change adds a new seccomp extension action for synchronizing thread
group seccomp filters and a prctl() for accessing that functionality,
as well as a flag for SECCOMP_EXT_ACT_FILTER to perform sync at filter
installation time.

When calling prctl(PR_SECCOMP_EXT, SECCOMP_EXT_ACT_FILTER, flags, filter)
with flags containing SECCOMP_FILTER_TSYNC, or when calling
prctl(PR_SECCOMP_EXT, SECCOMP_EXT_ACT_TSYNC, 0, 0), it will attempt to
synchronize all threads in current's threadgroup to its seccomp
filter program. This is possible iff all threads are using a filter that
is an ancestor to the filter current is attempting to synchronize to. NULL
filters (where the task is running as SECCOMP_MODE_NONE) are also treated
as ancestors allowing threads to be transitioned into SECCOMP_MODE_FILTER.
On success, 0 is returned. On failure, the pid of one of the failing
threads will be returned, with as many filters installed as possible.

The race conditions are against another thread calling TSYNC, another
thread performing a clone, and another thread changing its filter. The
seccomp write lock is sufficient for these cases, though the clone
case is assisted by the tasklist_lock so that new threads must have a
duplicate of its parent seccomp state when it appears on the tasklist.

Based on patches by Will Drewry.

Suggested-by: Julien Tinnes <jln@chromium.org>
Signed-off-by: Kees Cook <keescook@chromium.org>
seccomp: add seccomp mode that invokes LSM hook

If CONFIG_SECCOMP_LSM is defined, support an additional seccomp
mode where each syscall is policed by a new .intercept_syscall
LSM hook; the hook takes the syscall arguments and returns a
BPF response code indicating what action to take.  The default
implementation of the hook always returns SECCOMP_RET_ALLOW.

As with installing seccomp-bpf filters, enabling the seccomp
LSM mode requires that a task either has the CAP_SYS_ADMIN
capability, or that it has previously set no_new_privs.

Signed-off-by: David Drysdale <drysdale@google.com>
capsicum: add capability mode to filter syscalls

Add a default implementation of the new .intercept_syscall LSM
hook for Capsicum capability mode.  This mode disables all system
calls that access global namespaces, such as the filesystem or
IP:ports.

Add the ECAPMODE errno value to indicate that a particular syscall
has been rejected due to capability mode.

The set of allowed syscalls is intended to be as close as possible
to those allowed in the FreeBSD 10.x implementation of Capsicum, to
ease the porting of Capsicum-aware applications.

Signed-off-by: David Drysdale <drysdale@google.com>