From 9db11ce119062f10f7f06ac9bebe104cda60bb63 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 13 May 2020 14:11:26 -0700 Subject: [PATCH] UPSTREAM: seccomp: Report number of loaded filters in /proc/$pid/status 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 (cherry picked from commit c818c03b661cd769e035e41673d5543ba2ebda64) Signed-off-by: Jeff Vander Stoep Bug: 176068146 Change-Id: Ib189ea77511a6088d5d328706c77c88709d8d63e --- fs/proc/array.c | 2 ++ include/linux/seccomp.h | 2 ++ init/init_task.c | 3 +++ kernel/seccomp.c | 3 +++ 4 files changed, 10 insertions(+) diff --git a/fs/proc/array.c b/fs/proc/array.c index 46dcb6f0eccf..6d9e56d19b9e 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -342,6 +342,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)) { diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h index 84868d37b35d..262ff997870d 100644 --- a/include/linux/seccomp.h +++ b/include/linux/seccomp.h @@ -12,6 +12,7 @@ #ifdef CONFIG_SECCOMP #include +#include #include struct seccomp_filter; @@ -28,6 +29,7 @@ struct seccomp_filter; */ struct seccomp { int mode; + atomic_t filter_count; struct seccomp_filter *filter; }; diff --git a/init/init_task.c b/init/init_task.c index afaea5d7cb8a..b6fa82920e5d 100644 --- a/init/init_task.c +++ b/init/init_task.c @@ -193,6 +193,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); diff --git a/kernel/seccomp.c b/kernel/seccomp.c index f1bff3f17583..5b9ddc9b8a26 100644 --- a/kernel/seccomp.c +++ b/kernel/seccomp.c @@ -410,6 +410,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 @@ -551,6 +553,7 @@ static long seccomp_attach_filter(unsigned int flags, */ filter->prev = current->seccomp.filter; current->seccomp.filter = filter; + atomic_inc(¤t->seccomp.filter_count); /* Now that the new filter is in place, synchronize to all threads. */ if (flags & SECCOMP_FILTER_FLAG_TSYNC)