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. Suggested-by: Jann Horn <jannh@google.com> Link: https://lore.kernel.org/lkml/CAG48ez3Ofqp4crXGksLmZY6=fGrF_tWyUCg7PBkAetvbbOPeOA@mail.gmail.com/ Signed-off-by: YiFei Zhu <yifeifz2@illinois.edu> Signed-off-by: Kees Cook <keescook@chromium.org> Link: https://lore.kernel.org/r/94e663fa53136f5a11f432c661794d1ee7060779.1605101222.git.yifeifz2@illinois.edu
132 lines
3.5 KiB
C
132 lines
3.5 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef _LINUX_SECCOMP_H
|
|
#define _LINUX_SECCOMP_H
|
|
|
|
#include <uapi/linux/seccomp.h>
|
|
|
|
#define SECCOMP_FILTER_FLAG_MASK (SECCOMP_FILTER_FLAG_TSYNC | \
|
|
SECCOMP_FILTER_FLAG_LOG | \
|
|
SECCOMP_FILTER_FLAG_SPEC_ALLOW | \
|
|
SECCOMP_FILTER_FLAG_NEW_LISTENER | \
|
|
SECCOMP_FILTER_FLAG_TSYNC_ESRCH)
|
|
|
|
/* sizeof() the first published struct seccomp_notif_addfd */
|
|
#define SECCOMP_NOTIFY_ADDFD_SIZE_VER0 24
|
|
#define SECCOMP_NOTIFY_ADDFD_SIZE_LATEST SECCOMP_NOTIFY_ADDFD_SIZE_VER0
|
|
|
|
#ifdef CONFIG_SECCOMP
|
|
|
|
#include <linux/thread_info.h>
|
|
#include <linux/atomic.h>
|
|
#include <asm/seccomp.h>
|
|
|
|
struct seccomp_filter;
|
|
/**
|
|
* struct seccomp - the state of a seccomp'ed process
|
|
*
|
|
* @mode: indicates one of the valid values above for controlled
|
|
* system calls available to a process.
|
|
* @filter: must always point to a valid seccomp-filter or NULL as it is
|
|
* accessed without locking during system call entry.
|
|
*
|
|
* @filter must only be accessed from the context of current as there
|
|
* is no read locking.
|
|
*/
|
|
struct seccomp {
|
|
int mode;
|
|
atomic_t filter_count;
|
|
struct seccomp_filter *filter;
|
|
};
|
|
|
|
#ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER
|
|
extern int __secure_computing(const struct seccomp_data *sd);
|
|
static inline int secure_computing(void)
|
|
{
|
|
if (unlikely(test_thread_flag(TIF_SECCOMP)))
|
|
return __secure_computing(NULL);
|
|
return 0;
|
|
}
|
|
#else
|
|
extern void secure_computing_strict(int this_syscall);
|
|
#endif
|
|
|
|
extern long prctl_get_seccomp(void);
|
|
extern long prctl_set_seccomp(unsigned long, void __user *);
|
|
|
|
static inline int seccomp_mode(struct seccomp *s)
|
|
{
|
|
return s->mode;
|
|
}
|
|
|
|
#else /* CONFIG_SECCOMP */
|
|
|
|
#include <linux/errno.h>
|
|
|
|
struct seccomp { };
|
|
struct seccomp_filter { };
|
|
struct seccomp_data;
|
|
|
|
#ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER
|
|
static inline int secure_computing(void) { return 0; }
|
|
static inline int __secure_computing(const struct seccomp_data *sd) { return 0; }
|
|
#else
|
|
static inline void secure_computing_strict(int this_syscall) { return; }
|
|
#endif
|
|
|
|
static inline long prctl_get_seccomp(void)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
|
|
static inline long prctl_set_seccomp(unsigned long arg2, char __user *arg3)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
|
|
static inline int seccomp_mode(struct seccomp *s)
|
|
{
|
|
return SECCOMP_MODE_DISABLED;
|
|
}
|
|
#endif /* CONFIG_SECCOMP */
|
|
|
|
#ifdef CONFIG_SECCOMP_FILTER
|
|
extern void seccomp_filter_release(struct task_struct *tsk);
|
|
extern void get_seccomp_filter(struct task_struct *tsk);
|
|
#else /* CONFIG_SECCOMP_FILTER */
|
|
static inline void seccomp_filter_release(struct task_struct *tsk)
|
|
{
|
|
return;
|
|
}
|
|
static inline void get_seccomp_filter(struct task_struct *tsk)
|
|
{
|
|
return;
|
|
}
|
|
#endif /* CONFIG_SECCOMP_FILTER */
|
|
|
|
#if defined(CONFIG_SECCOMP_FILTER) && defined(CONFIG_CHECKPOINT_RESTORE)
|
|
extern long seccomp_get_filter(struct task_struct *task,
|
|
unsigned long filter_off, void __user *data);
|
|
extern long seccomp_get_metadata(struct task_struct *task,
|
|
unsigned long filter_off, void __user *data);
|
|
#else
|
|
static inline long seccomp_get_filter(struct task_struct *task,
|
|
unsigned long n, void __user *data)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
static inline long seccomp_get_metadata(struct task_struct *task,
|
|
unsigned long filter_off,
|
|
void __user *data)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
#endif /* CONFIG_SECCOMP_FILTER && CONFIG_CHECKPOINT_RESTORE */
|
|
|
|
#ifdef CONFIG_SECCOMP_CACHE_DEBUG
|
|
struct seq_file;
|
|
|
|
int proc_pid_seccomp_cache(struct seq_file *m, struct pid_namespace *ns,
|
|
struct pid *pid, struct task_struct *task);
|
|
#endif
|
|
#endif /* _LINUX_SECCOMP_H */
|