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

Unified · Split

4 files
  1. arch/Kconfig +17 −0
  2. fs/proc/base.c +6 −0
  3. include/linux/seccomp.h +7 −0
  4. kernel/seccomp.c +59 −0
arch/Kconfig+17−0
@@ -486,6 +486,9 @@ config HAVE_ARCH_SECCOMP_FILTER · 485 unmodified lines
486 - secure_computing return value is checked and a return value of -1486 - secure_computing return value is checked and a return value of -1
487 results in the system call being skipped immediately.487 results in the system call being skipped immediately.
488 - seccomp syscall wired up488 - seccomp syscall wired up
489 - if !HAVE_SPARSE_SYSCALL_NR, have SECCOMP_ARCH_NATIVE,
490 SECCOMP_ARCH_NATIVE_NR, SECCOMP_ARCH_NATIVE_NAME defined. If
491 COMPAT is supported, have the SECCOMP_ARCH_COMPAT* defines too.
489 492
490config SECCOMP493config SECCOMP
491 prompt "Enable seccomp to safely execute untrusted bytecode"494 prompt "Enable seccomp to safely execute untrusted bytecode"
@@ -514,6 +517,20 @@ config SECCOMP_FILTER · 22 unmodified lines
514 517
515 See Documentation/userspace-api/seccomp_filter.rst for details.518 See Documentation/userspace-api/seccomp_filter.rst for details.
516 519
520config SECCOMP_CACHE_DEBUG
521 bool "Show seccomp filter cache status in /proc/pid/seccomp_cache"
522 depends on SECCOMP_FILTER && !HAVE_SPARSE_SYSCALL_NR
523 depends on PROC_FS
524 help
525 This enables the /proc/pid/seccomp_cache interface to monitor
526 seccomp cache data. The file format is subject to change. Reading
527 the file requires CAP_SYS_ADMIN.
528
529 This option is for debugging only. Enabling presents the risk that
530 an adversary may be able to infer the seccomp filter logic.
531
532 If unsure, say N.
533
517config HAVE_ARCH_STACKLEAK534config HAVE_ARCH_STACKLEAK
518 bool535 bool
519 help536 help
fs/proc/base.c+6−0
@@ -3263,6 +3263,9 @@ static const struct pid_entry tgid_base_stuff[] = { · 3262 unmodified lines
3263#ifdef CONFIG_PROC_PID_ARCH_STATUS3263#ifdef CONFIG_PROC_PID_ARCH_STATUS
3264 ONE("arch_status", S_IRUGO, proc_pid_arch_status),3264 ONE("arch_status", S_IRUGO, proc_pid_arch_status),
3265#endif3265#endif
3266#ifdef CONFIG_SECCOMP_CACHE_DEBUG
3267 ONE("seccomp_cache", S_IRUSR, proc_pid_seccomp_cache),
3268#endif
3266};3269};
3267 3270
3268static int proc_tgid_base_readdir(struct file *file, struct dir_context *ctx)3271static int proc_tgid_base_readdir(struct file *file, struct dir_context *ctx)
@@ -3592,6 +3595,9 @@ static const struct pid_entry tid_base_stuff[] = { · 323 unmodified lines
3592#ifdef CONFIG_PROC_PID_ARCH_STATUS3595#ifdef CONFIG_PROC_PID_ARCH_STATUS
3593 ONE("arch_status", S_IRUGO, proc_pid_arch_status),3596 ONE("arch_status", S_IRUGO, proc_pid_arch_status),
3594#endif3597#endif
3598#ifdef CONFIG_SECCOMP_CACHE_DEBUG
3599 ONE("seccomp_cache", S_IRUSR, proc_pid_seccomp_cache),
3600#endif
3595};3601};
3596 3602
3597static int proc_tid_base_readdir(struct file *file, struct dir_context *ctx)3603static int proc_tid_base_readdir(struct file *file, struct dir_context *ctx)
include/linux/seccomp.h+7−0
@@ -121,4 +121,11 @@ static inline long seccomp_get_metadata(struct task_struct *task, · 120 unmodified lines
121 return -EINVAL;121 return -EINVAL;
122}122}
123#endif /* CONFIG_SECCOMP_FILTER && CONFIG_CHECKPOINT_RESTORE */123#endif /* CONFIG_SECCOMP_FILTER && CONFIG_CHECKPOINT_RESTORE */
124
125#ifdef CONFIG_SECCOMP_CACHE_DEBUG
126struct seq_file;
127
128int proc_pid_seccomp_cache(struct seq_file *m, struct pid_namespace *ns,
129 struct pid *pid, struct task_struct *task);
130#endif
124#endif /* _LINUX_SECCOMP_H */131#endif /* _LINUX_SECCOMP_H */
kernel/seccomp.c+59−0
@@ -553,6 +553,9 @@ void seccomp_filter_release(struct task_struct *tsk) · 552 unmodified lines
553{553{
554 struct seccomp_filter *orig = tsk->seccomp.filter;554 struct seccomp_filter *orig = tsk->seccomp.filter;
555 555
556 /* We are effectively holding the siglock by not having any sighand. */
557 WARN_ON(tsk->sighand != NULL);
558
556 /* Detach task from its filter tree. */559 /* Detach task from its filter tree. */
557 tsk->seccomp.filter = NULL;560 tsk->seccomp.filter = NULL;
558 __seccomp_filter_release(orig);561 __seccomp_filter_release(orig);
@@ -2335,3 +2338,59 @@ static int __init seccomp_sysctl_init(void) · 1776 unmodified lines
2335device_initcall(seccomp_sysctl_init)2338device_initcall(seccomp_sysctl_init)
2336 2339
2337#endif /* CONFIG_SYSCTL */2340#endif /* CONFIG_SYSCTL */
2341
2342#ifdef CONFIG_SECCOMP_CACHE_DEBUG
2343/* Currently CONFIG_SECCOMP_CACHE_DEBUG implies SECCOMP_ARCH_NATIVE */
2344static 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
2357int 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