seccomp: Switch from atomic_t to recount_t
authorKees Cook <keescook@chromium.org>
Mon, 26 Jun 2017 16:24:00 +0000 (09:24 -0700)
committerKees Cook <keescook@chromium.org>
Mon, 26 Jun 2017 16:24:00 +0000 (09:24 -0700)
This switches the seccomp usage tracking from atomic_t to refcount_t to
gain refcount overflow protections.

Cc: Elena Reshetova <elena.reshetova@intel.com>
Cc: David Windsor <dwindsor@gmail.com>
Cc: Hans Liljestrand <hans.liljestrand@aalto.fi>
Signed-off-by: Kees Cook <keescook@chromium.org>
kernel/seccomp.c

index fce83885b7eff603998a8058e5cf0fa41e1dc64c..98b59b5db90baae53b091afe807c133e6027d081 100644 (file)
@@ -13,7 +13,7 @@
  *        of Berkeley Packet Filters/Linux Socket Filters.
  */
 
-#include <linux/atomic.h>
+#include <linux/refcount.h>
 #include <linux/audit.h>
 #include <linux/compat.h>
 #include <linux/coredump.h>
@@ -56,7 +56,7 @@
  * to a task_struct (other than @usage).
  */
 struct seccomp_filter {
-       atomic_t usage;
+       refcount_t usage;
        struct seccomp_filter *prev;
        struct bpf_prog *prog;
 };
@@ -378,7 +378,7 @@ static struct seccomp_filter *seccomp_prepare_filter(struct sock_fprog *fprog)
                return ERR_PTR(ret);
        }
 
-       atomic_set(&sfilter->usage, 1);
+       refcount_set(&sfilter->usage, 1);
 
        return sfilter;
 }
@@ -465,7 +465,7 @@ void get_seccomp_filter(struct task_struct *tsk)
        if (!orig)
                return;
        /* Reference count is bounded by the number of total processes. */
-       atomic_inc(&orig->usage);
+       refcount_inc(&orig->usage);
 }
 
 static inline void seccomp_filter_free(struct seccomp_filter *filter)
@@ -481,7 +481,7 @@ void put_seccomp_filter(struct task_struct *tsk)
 {
        struct seccomp_filter *orig = tsk->seccomp.filter;
        /* Clean up single-reference branches iteratively. */
-       while (orig && atomic_dec_and_test(&orig->usage)) {
+       while (orig && refcount_dec_and_test(&orig->usage)) {
                struct seccomp_filter *freeme = orig;
                orig = orig->prev;
                seccomp_filter_free(freeme);