seccomp: introduce writer locking
authorKees Cook <keescook@chromium.org>
Fri, 27 Jun 2014 22:18:48 +0000 (15:18 -0700)
committerJP Abgrall <jpa@google.com>
Thu, 28 Aug 2014 01:53:30 +0000 (01:53 +0000)
commit743266ae255c44edeb50911c191bf8083ea683dc
tree37aee83e50d2af1a6558f8a0723dae50ac3ac8b8
parent3497a88f5510c809ca10deac3030493eabba65d7
seccomp: introduce writer locking

Normally, task_struct.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-thread filter pointer updates, writes to the
seccomp fields are now protected by the sighand spinlock (which is shared
by all threads in the thread group). 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 additionally
moved under the sighand lock. Then parent and child are certain have
the same seccomp state when they exit the lock.

Based on patches by Will Drewry and David Drysdale.

Signed-off-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Oleg Nesterov <oleg@redhat.com>
Reviewed-by: Andy Lutomirski <luto@amacapital.net>
Conflicts:
kernel/fork.c

Change-Id: Ie01ece43b610867013f7d0e0a2a7be0b9077630f
include/linux/seccomp.h
kernel/fork.c
kernel/seccomp.c