OSDN Git Service

seccomp: Report number of loaded filters in /proc/$pid/status
authorKees Cook <keescook@chromium.org>
Wed, 13 May 2020 21:11:26 +0000 (14:11 -0700)
committerKees Cook <keescook@chromium.org>
Fri, 10 Jul 2020 23:01:51 +0000 (16:01 -0700)
A common question asked when debugging seccomp filters is "how many
filters are attached to your process?" Provide a way to easily answer
this question through /proc/$pid/status with a "Seccomp_filters" line.

Signed-off-by: Kees Cook <keescook@chromium.org>
fs/proc/array.c
include/linux/seccomp.h
init/init_task.c
kernel/seccomp.c

index 55ecbeb..65ec202 100644 (file)
@@ -341,6 +341,8 @@ static inline void task_seccomp(struct seq_file *m, struct task_struct *p)
        seq_put_decimal_ull(m, "NoNewPrivs:\t", task_no_new_privs(p));
 #ifdef CONFIG_SECCOMP
        seq_put_decimal_ull(m, "\nSeccomp:\t", p->seccomp.mode);
+       seq_put_decimal_ull(m, "\nSeccomp_filters:\t",
+                           atomic_read(&p->seccomp.filter_count));
 #endif
        seq_puts(m, "\nSpeculation_Store_Bypass:\t");
        switch (arch_prctl_spec_ctrl_get(p, PR_SPEC_STORE_BYPASS)) {
index 4192369..2ec2720 100644 (file)
@@ -13,6 +13,7 @@
 #ifdef CONFIG_SECCOMP
 
 #include <linux/thread_info.h>
+#include <linux/atomic.h>
 #include <asm/seccomp.h>
 
 struct seccomp_filter;
@@ -29,6 +30,7 @@ struct seccomp_filter;
  */
 struct seccomp {
        int mode;
+       atomic_t filter_count;
        struct seccomp_filter *filter;
 };
 
index 15089d1..a3eb384 100644 (file)
@@ -204,6 +204,9 @@ struct task_struct init_task
 #ifdef CONFIG_SECURITY
        .security       = NULL,
 #endif
+#ifdef CONFIG_SECCOMP
+       .seccomp        = { .filter_count = ATOMIC_INIT(0) },
+#endif
 };
 EXPORT_SYMBOL(init_task);
 
index d653d84..f387e50 100644 (file)
@@ -398,6 +398,8 @@ static inline void seccomp_sync_threads(unsigned long flags)
                put_seccomp_filter(thread);
                smp_store_release(&thread->seccomp.filter,
                                  caller->seccomp.filter);
+               atomic_set(&thread->seccomp.filter_count,
+                          atomic_read(&thread->seccomp.filter_count));
 
                /*
                 * Don't let an unprivileged task work around
@@ -544,6 +546,7 @@ static long seccomp_attach_filter(unsigned int flags,
         */
        filter->prev = current->seccomp.filter;
        current->seccomp.filter = filter;
+       atomic_inc(&current->seccomp.filter_count);
 
        /* Now that the new filter is in place, synchronize to all threads. */
        if (flags & SECCOMP_FILTER_FLAG_TSYNC)