mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-12 05:48:40 +00:00
![Tyler Hicks](/assets/img/avatar_default.png)
Add a new filter flag, SECCOMP_FILTER_FLAG_LOG, that enables logging for all actions except for SECCOMP_RET_ALLOW for the given filter. SECCOMP_RET_KILL actions are always logged, when "kill" is in the actions_logged sysctl, and SECCOMP_RET_ALLOW actions are never logged, regardless of this flag. This flag can be used to create noisy filters that result in all non-allowed actions to be logged. A process may have one noisy filter, which is loaded with this flag, as well as a quiet filter that's not loaded with this flag. This allows for the actions in a set of filters to be selectively conveyed to the admin. Since a system could have a large number of allocated seccomp_filter structs, struct packing was taken in consideration. On 64 bit x86, the new log member takes up one byte of an existing four byte hole in the struct. On 32 bit x86, the new log member creates a new four byte hole (unavoidable) and consumes one of those bytes. Unfortunately, the tests added for SECCOMP_FILTER_FLAG_LOG are not capable of inspecting the audit log to verify that the actions taken in the filter were logged. With this patch, the logic for deciding if an action will be logged is: if action == RET_ALLOW: do not log else if action == RET_KILL && RET_KILL in actions_logged: log else if filter-requests-logging && action in actions_logged: log else if audit_enabled && process-is-being-audited: log else: do not log Signed-off-by: Tyler Hicks <tyhicks@canonical.com> Signed-off-by: Kees Cook <keescook@chromium.org>
104 lines
2.6 KiB
C
104 lines
2.6 KiB
C
#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)
|
|
|
|
#ifdef CONFIG_SECCOMP
|
|
|
|
#include <linux/thread_info.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;
|
|
struct seccomp_filter *filter;
|
|
};
|
|
|
|
#ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER
|
|
extern int __secure_computing(const struct seccomp_data *sd);
|
|
static inline int secure_computing(const struct seccomp_data *sd)
|
|
{
|
|
if (unlikely(test_thread_flag(TIF_SECCOMP)))
|
|
return __secure_computing(sd);
|
|
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, char __user *);
|
|
|
|
static inline int seccomp_mode(struct seccomp *s)
|
|
{
|
|
return s->mode;
|
|
}
|
|
|
|
#else /* CONFIG_SECCOMP */
|
|
|
|
#include <linux/errno.h>
|
|
|
|
struct seccomp { };
|
|
struct seccomp_filter { };
|
|
|
|
#ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER
|
|
static inline int secure_computing(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 put_seccomp_filter(struct task_struct *tsk);
|
|
extern void get_seccomp_filter(struct task_struct *tsk);
|
|
#else /* CONFIG_SECCOMP_FILTER */
|
|
static inline void put_seccomp_filter(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);
|
|
#else
|
|
static inline long seccomp_get_filter(struct task_struct *task,
|
|
unsigned long n, void __user *data)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
#endif /* CONFIG_SECCOMP_FILTER && CONFIG_CHECKPOINT_RESTORE */
|
|
#endif /* _LINUX_SECCOMP_H */
|