History

seccomp/cache: Report cache data through /proc/pid/seccomp_cache

Currently the kernel does not provide an infrastructure to translate architecture numbers to a human-readable name. Translating syscall numbers to syscall names is possible through FTRACE_SYSCALL infrastructure but it does not provide support for compat syscalls. This will create a file for each PID as /proc/pid/seccomp_cache. The file will be empty when no seccomp filters are loaded, or be in the format of: <arch name> <decimal syscall number> <ALLOW | FILTER> where ALLOW means the cache is guaranteed to allow the syscall, and filter means the cache will pass the syscall to the BPF filter. For the docker default profile on x86_64 it looks like: x86_64 0 ALLOW x86_64 1 ALLOW x86_64 2 ALLOW x86_64 3 ALLOW [...] x86_64 132 ALLOW x86_64 133 ALLOW x86_64 134 FILTER x86_64 135 FILTER x86_64 136 FILTER x86_64 137 ALLOW x86_64 138 ALLOW x86_64 139 FILTER x86_64 140 ALLOW x86_64 141 ALLOW [...] This file is guarded by CONFIG_SECCOMP_CACHE_DEBUG with a default of N because I think certain users of seccomp might not want the application to know which syscalls are definitely usable. For the same reason, it is also guarded by CAP_SYS_ADMIN.

YiFei Zhu committed 6 years ago

Commit 0d8315d1 parent 445247b4 files · +89 −0Browse files

Showing the changes to kernel (1 of 4 files). Show all

Unified · Split

kernel/seccomp.c+59−0
@@ -553,6 +553,9 @@ void seccomp_filter_release(struct task_struct *tsk) · 552 unmodified lines
553553 {
554554 struct seccomp_filter *orig = tsk->seccomp.filter;
555555
556+ /* We are effectively holding the siglock by not having any sighand. */
557+ WARN_ON(tsk->sighand != NULL);
558+
556559 /* Detach task from its filter tree. */
557560 tsk->seccomp.filter = NULL;
558561 __seccomp_filter_release(orig);
@@ -2335,3 +2338,59 @@ static int __init seccomp_sysctl_init(void) · 1776 unmodified lines
23352338 device_initcall(seccomp_sysctl_init)
23362339
23372340 #endif /* CONFIG_SYSCTL */
2341+
2342+#ifdef CONFIG_SECCOMP_CACHE_DEBUG
2343+/* Currently CONFIG_SECCOMP_CACHE_DEBUG implies SECCOMP_ARCH_NATIVE */
2344+static void proc_pid_seccomp_cache_arch(struct seq_file *m, const char *name,
2345+ const void *bitmap, size_t bitmap_size)
2346+{
2347+ int nr;
2348+
2349+ for (nr = 0; nr < bitmap_size; nr++) {
2350+ bool cached = test_bit(nr, bitmap);
2351+ char *status = cached ? "ALLOW" : "FILTER";
2352+
2353+ seq_printf(m, "%s %d %s\n", name, nr, status);
2354+ }
2355+}
2356+
2357+int proc_pid_seccomp_cache(struct seq_file *m, struct pid_namespace *ns,
2358+ struct pid *pid, struct task_struct *task)
2359+{
2360+ struct seccomp_filter *f;
2361+ unsigned long flags;
2362+
2363+ /*
2364+ * We don't want some sandboxed process to know what their seccomp
2365+ * filters consist of.
2366+ */
2367+ if (!file_ns_capable(m->file, &init_user_ns, CAP_SYS_ADMIN))
2368+ return -EACCES;
2369+
2370+ if (!lock_task_sighand(task, &flags))
2371+ return -ESRCH;
2372+
2373+ f = READ_ONCE(task->seccomp.filter);
2374+ if (!f) {
2375+ unlock_task_sighand(task, &flags);
2376+ return 0;
2377+ }
2378+
2379+ /* prevent filter from being freed while we are printing it */
2380+ __get_seccomp_filter(f);
2381+ unlock_task_sighand(task, &flags);
2382+
2383+ proc_pid_seccomp_cache_arch(m, SECCOMP_ARCH_NATIVE_NAME,
2384+ f->cache.allow_native,
2385+ SECCOMP_ARCH_NATIVE_NR);
2386+
2387+#ifdef SECCOMP_ARCH_COMPAT
2388+ proc_pid_seccomp_cache_arch(m, SECCOMP_ARCH_COMPAT_NAME,
2389+ f->cache.allow_compat,
2390+ SECCOMP_ARCH_COMPAT_NR);
2391+#endif /* SECCOMP_ARCH_COMPAT */
2392+
2393+ __put_seccomp_filter(f);
2394+ return 0;
2395+}
2396+#endif /* CONFIG_SECCOMP_CACHE_DEBUG */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t