summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2020-05-13 14:11:26 -0700
committerKees Cook <keescook@chromium.org>2020-07-10 16:01:51 -0700
commitc818c03b661cd769e035e41673d5543ba2ebda64 (patch)
treeceb9cf9666ce0e0e3964c1ff1a0a5949de471cf6
parente4d05028a07f505a08802a6d1b11674c149df2b3 (diff)
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 <keescook@chromium.org>
-rw-r--r--fs/proc/array.c2
-rw-r--r--include/linux/seccomp.h2
-rw-r--r--init/init_task.c3
-rw-r--r--kernel/seccomp.c3
4 files changed, 10 insertions, 0 deletions
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 55ecbeb3a721..65ec2029fa80 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -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)) {
diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
index 4192369b8418..2ec2720f83cc 100644
--- a/include/linux/seccomp.h
+++ b/include/linux/seccomp.h
@@ -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;
};
diff --git a/init/init_task.c b/init/init_task.c
index 15089d15010a..a3eb3847e1f4 100644
--- a/init/init_task.c
+++ b/init/init_task.c
@@ -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);
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index d653d8426de9..f387e5004c29 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -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)