Commit 59f5cf44 authored by Tyler Hicks's avatar Tyler Hicks Committed by Kees Cook

seccomp: Action to log before allowing

Add a new action, SECCOMP_RET_LOG, that logs a syscall before allowing
the syscall. At the implementation level, this action is identical to
the existing SECCOMP_RET_ALLOW action. However, it can be very useful when
initially developing a seccomp filter for an application. The developer
can set the default action to be SECCOMP_RET_LOG, maybe mark any
obviously needed syscalls with SECCOMP_RET_ALLOW, and then put the
application through its paces. A list of syscalls that triggered the
default action (SECCOMP_RET_LOG) can be easily gleaned from the logs and
that list can be used to build the syscall whitelist. Finally, the
developer can change the default action to the desired value.

This provides a more friendly experience than seeing the application get
killed, then updating the filter and rebuilding the app, seeing the
application get killed due to a different syscall, then updating the
filter and rebuilding the app, etc.

The functionality is similar to what's supported by the various LSMs.
SELinux has permissive mode, AppArmor has complain mode, SMACK has
bring-up mode, etc.

SECCOMP_RET_LOG is given a lower value than SECCOMP_RET_ALLOW as allow
while logging is slightly more restrictive than quietly allowing.

Unfortunately, the tests added for SECCOMP_RET_LOG are not capable of
inspecting the audit log to verify that the syscall was 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 action == RET_LOG && RET_LOG 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: default avatarTyler Hicks <tyhicks@canonical.com>
Signed-off-by: default avatarKees Cook <keescook@chromium.org>
parent e66a3997
...@@ -141,6 +141,15 @@ In precedence order, they are: ...@@ -141,6 +141,15 @@ In precedence order, they are:
allow use of ptrace, even of other sandboxed processes, without allow use of ptrace, even of other sandboxed processes, without
extreme care; ptracers can use this mechanism to escape.) extreme care; ptracers can use this mechanism to escape.)
``SECCOMP_RET_LOG``:
Results in the system call being executed after it is logged. This
should be used by application developers to learn which syscalls their
application needs without having to iterate through multiple test and
development cycles to build the list.
This action will only be logged if "log" is present in the
actions_logged sysctl string.
``SECCOMP_RET_ALLOW``: ``SECCOMP_RET_ALLOW``:
Results in the system call being executed. Results in the system call being executed.
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */ #define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */
#define SECCOMP_RET_ERRNO 0x00050000U /* returns an errno */ #define SECCOMP_RET_ERRNO 0x00050000U /* returns an errno */
#define SECCOMP_RET_TRACE 0x7ff00000U /* pass to a tracer or disallow */ #define SECCOMP_RET_TRACE 0x7ff00000U /* pass to a tracer or disallow */
#define SECCOMP_RET_LOG 0x7ffc0000U /* allow after logging */
#define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */ #define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */
/* Masks for the return value sections. */ /* Masks for the return value sections. */
......
...@@ -533,10 +533,12 @@ static void seccomp_send_sigsys(int syscall, int reason) ...@@ -533,10 +533,12 @@ static void seccomp_send_sigsys(int syscall, int reason)
#define SECCOMP_LOG_TRAP (1 << 2) #define SECCOMP_LOG_TRAP (1 << 2)
#define SECCOMP_LOG_ERRNO (1 << 3) #define SECCOMP_LOG_ERRNO (1 << 3)
#define SECCOMP_LOG_TRACE (1 << 4) #define SECCOMP_LOG_TRACE (1 << 4)
#define SECCOMP_LOG_ALLOW (1 << 5) #define SECCOMP_LOG_LOG (1 << 5)
#define SECCOMP_LOG_ALLOW (1 << 6)
static u32 seccomp_actions_logged = SECCOMP_LOG_KILL | SECCOMP_LOG_TRAP | static u32 seccomp_actions_logged = SECCOMP_LOG_KILL | SECCOMP_LOG_TRAP |
SECCOMP_LOG_ERRNO | SECCOMP_LOG_TRACE; SECCOMP_LOG_ERRNO | SECCOMP_LOG_TRACE |
SECCOMP_LOG_LOG;
static inline void seccomp_log(unsigned long syscall, long signr, u32 action, static inline void seccomp_log(unsigned long syscall, long signr, u32 action,
bool requested) bool requested)
...@@ -555,15 +557,18 @@ static inline void seccomp_log(unsigned long syscall, long signr, u32 action, ...@@ -555,15 +557,18 @@ static inline void seccomp_log(unsigned long syscall, long signr, u32 action,
case SECCOMP_RET_TRACE: case SECCOMP_RET_TRACE:
log = requested && seccomp_actions_logged & SECCOMP_LOG_TRACE; log = requested && seccomp_actions_logged & SECCOMP_LOG_TRACE;
break; break;
case SECCOMP_RET_LOG:
log = seccomp_actions_logged & SECCOMP_LOG_LOG;
break;
case SECCOMP_RET_KILL: case SECCOMP_RET_KILL:
default: default:
log = seccomp_actions_logged & SECCOMP_LOG_KILL; log = seccomp_actions_logged & SECCOMP_LOG_KILL;
} }
/* /*
* Force an audit message to be emitted when the action is RET_KILL or * Force an audit message to be emitted when the action is RET_KILL,
* the FILTER_FLAG_LOG bit was set and the action is allowed to be * RET_LOG, or the FILTER_FLAG_LOG bit was set and the action is
* logged by the admin. * allowed to be logged by the admin.
*/ */
if (log) if (log)
return __audit_seccomp(syscall, signr, action); return __audit_seccomp(syscall, signr, action);
...@@ -699,6 +704,10 @@ static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd, ...@@ -699,6 +704,10 @@ static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd,
return 0; return 0;
case SECCOMP_RET_LOG:
seccomp_log(this_syscall, 0, action, true);
return 0;
case SECCOMP_RET_ALLOW: case SECCOMP_RET_ALLOW:
/* /*
* Note that the "match" filter will always be NULL for * Note that the "match" filter will always be NULL for
...@@ -873,6 +882,7 @@ static long seccomp_get_action_avail(const char __user *uaction) ...@@ -873,6 +882,7 @@ static long seccomp_get_action_avail(const char __user *uaction)
case SECCOMP_RET_TRAP: case SECCOMP_RET_TRAP:
case SECCOMP_RET_ERRNO: case SECCOMP_RET_ERRNO:
case SECCOMP_RET_TRACE: case SECCOMP_RET_TRACE:
case SECCOMP_RET_LOG:
case SECCOMP_RET_ALLOW: case SECCOMP_RET_ALLOW:
break; break;
default: default:
...@@ -1023,12 +1033,14 @@ long seccomp_get_filter(struct task_struct *task, unsigned long filter_off, ...@@ -1023,12 +1033,14 @@ long seccomp_get_filter(struct task_struct *task, unsigned long filter_off,
#define SECCOMP_RET_TRAP_NAME "trap" #define SECCOMP_RET_TRAP_NAME "trap"
#define SECCOMP_RET_ERRNO_NAME "errno" #define SECCOMP_RET_ERRNO_NAME "errno"
#define SECCOMP_RET_TRACE_NAME "trace" #define SECCOMP_RET_TRACE_NAME "trace"
#define SECCOMP_RET_LOG_NAME "log"
#define SECCOMP_RET_ALLOW_NAME "allow" #define SECCOMP_RET_ALLOW_NAME "allow"
static const char seccomp_actions_avail[] = SECCOMP_RET_KILL_NAME " " static const char seccomp_actions_avail[] = SECCOMP_RET_KILL_NAME " "
SECCOMP_RET_TRAP_NAME " " SECCOMP_RET_TRAP_NAME " "
SECCOMP_RET_ERRNO_NAME " " SECCOMP_RET_ERRNO_NAME " "
SECCOMP_RET_TRACE_NAME " " SECCOMP_RET_TRACE_NAME " "
SECCOMP_RET_LOG_NAME " "
SECCOMP_RET_ALLOW_NAME; SECCOMP_RET_ALLOW_NAME;
struct seccomp_log_name { struct seccomp_log_name {
...@@ -1041,6 +1053,7 @@ static const struct seccomp_log_name seccomp_log_names[] = { ...@@ -1041,6 +1053,7 @@ static const struct seccomp_log_name seccomp_log_names[] = {
{ SECCOMP_LOG_TRAP, SECCOMP_RET_TRAP_NAME }, { SECCOMP_LOG_TRAP, SECCOMP_RET_TRAP_NAME },
{ SECCOMP_LOG_ERRNO, SECCOMP_RET_ERRNO_NAME }, { SECCOMP_LOG_ERRNO, SECCOMP_RET_ERRNO_NAME },
{ SECCOMP_LOG_TRACE, SECCOMP_RET_TRACE_NAME }, { SECCOMP_LOG_TRACE, SECCOMP_RET_TRACE_NAME },
{ SECCOMP_LOG_LOG, SECCOMP_RET_LOG_NAME },
{ SECCOMP_LOG_ALLOW, SECCOMP_RET_ALLOW_NAME }, { SECCOMP_LOG_ALLOW, SECCOMP_RET_ALLOW_NAME },
{ } { }
}; };
......
...@@ -74,7 +74,12 @@ ...@@ -74,7 +74,12 @@
#define SECCOMP_RET_ERRNO 0x00050000U /* returns an errno */ #define SECCOMP_RET_ERRNO 0x00050000U /* returns an errno */
#define SECCOMP_RET_TRACE 0x7ff00000U /* pass to a tracer or disallow */ #define SECCOMP_RET_TRACE 0x7ff00000U /* pass to a tracer or disallow */
#define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */ #define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */
#endif
#ifndef SECCOMP_RET_LOG
#define SECCOMP_RET_LOG 0x7ffc0000U /* allow after logging */
#endif
#ifndef SECCOMP_RET_ACTION
/* Masks for the return value sections. */ /* Masks for the return value sections. */
#define SECCOMP_RET_ACTION 0x7fff0000U #define SECCOMP_RET_ACTION 0x7fff0000U
#define SECCOMP_RET_DATA 0x0000ffffU #define SECCOMP_RET_DATA 0x0000ffffU
...@@ -342,6 +347,28 @@ TEST(empty_prog) ...@@ -342,6 +347,28 @@ TEST(empty_prog)
EXPECT_EQ(EINVAL, errno); EXPECT_EQ(EINVAL, errno);
} }
TEST(log_all)
{
struct sock_filter filter[] = {
BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_LOG),
};
struct sock_fprog prog = {
.len = (unsigned short)ARRAY_SIZE(filter),
.filter = filter,
};
long ret;
pid_t parent = getppid();
ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
ASSERT_EQ(0, ret);
/* getppid() should succeed and be logged (no check for logging) */
EXPECT_EQ(parent, syscall(__NR_getppid));
}
TEST_SIGNAL(unknown_ret_is_kill_inside, SIGSYS) TEST_SIGNAL(unknown_ret_is_kill_inside, SIGSYS)
{ {
struct sock_filter filter[] = { struct sock_filter filter[] = {
...@@ -756,6 +783,7 @@ TEST_F(TRAP, handler) ...@@ -756,6 +783,7 @@ TEST_F(TRAP, handler)
FIXTURE_DATA(precedence) { FIXTURE_DATA(precedence) {
struct sock_fprog allow; struct sock_fprog allow;
struct sock_fprog log;
struct sock_fprog trace; struct sock_fprog trace;
struct sock_fprog error; struct sock_fprog error;
struct sock_fprog trap; struct sock_fprog trap;
...@@ -767,6 +795,13 @@ FIXTURE_SETUP(precedence) ...@@ -767,6 +795,13 @@ FIXTURE_SETUP(precedence)
struct sock_filter allow_insns[] = { struct sock_filter allow_insns[] = {
BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW), BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
}; };
struct sock_filter log_insns[] = {
BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
offsetof(struct seccomp_data, nr)),
BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 1, 0),
BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_LOG),
};
struct sock_filter trace_insns[] = { struct sock_filter trace_insns[] = {
BPF_STMT(BPF_LD|BPF_W|BPF_ABS, BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
offsetof(struct seccomp_data, nr)), offsetof(struct seccomp_data, nr)),
...@@ -803,6 +838,7 @@ FIXTURE_SETUP(precedence) ...@@ -803,6 +838,7 @@ FIXTURE_SETUP(precedence)
memcpy(self->_x.filter, &_x##_insns, sizeof(_x##_insns)); \ memcpy(self->_x.filter, &_x##_insns, sizeof(_x##_insns)); \
self->_x.len = (unsigned short)ARRAY_SIZE(_x##_insns) self->_x.len = (unsigned short)ARRAY_SIZE(_x##_insns)
FILTER_ALLOC(allow); FILTER_ALLOC(allow);
FILTER_ALLOC(log);
FILTER_ALLOC(trace); FILTER_ALLOC(trace);
FILTER_ALLOC(error); FILTER_ALLOC(error);
FILTER_ALLOC(trap); FILTER_ALLOC(trap);
...@@ -813,6 +849,7 @@ FIXTURE_TEARDOWN(precedence) ...@@ -813,6 +849,7 @@ FIXTURE_TEARDOWN(precedence)
{ {
#define FILTER_FREE(_x) if (self->_x.filter) free(self->_x.filter) #define FILTER_FREE(_x) if (self->_x.filter) free(self->_x.filter)
FILTER_FREE(allow); FILTER_FREE(allow);
FILTER_FREE(log);
FILTER_FREE(trace); FILTER_FREE(trace);
FILTER_FREE(error); FILTER_FREE(error);
FILTER_FREE(trap); FILTER_FREE(trap);
...@@ -830,6 +867,8 @@ TEST_F(precedence, allow_ok) ...@@ -830,6 +867,8 @@ TEST_F(precedence, allow_ok)
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow); ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
ASSERT_EQ(0, ret); ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log);
ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace); ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
ASSERT_EQ(0, ret); ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error); ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
...@@ -854,6 +893,8 @@ TEST_F_SIGNAL(precedence, kill_is_highest, SIGSYS) ...@@ -854,6 +893,8 @@ TEST_F_SIGNAL(precedence, kill_is_highest, SIGSYS)
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow); ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
ASSERT_EQ(0, ret); ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log);
ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace); ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
ASSERT_EQ(0, ret); ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error); ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
...@@ -885,6 +926,8 @@ TEST_F_SIGNAL(precedence, kill_is_highest_in_any_order, SIGSYS) ...@@ -885,6 +926,8 @@ TEST_F_SIGNAL(precedence, kill_is_highest_in_any_order, SIGSYS)
ASSERT_EQ(0, ret); ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error); ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
ASSERT_EQ(0, ret); ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log);
ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace); ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
ASSERT_EQ(0, ret); ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trap); ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trap);
...@@ -906,6 +949,8 @@ TEST_F_SIGNAL(precedence, trap_is_second, SIGSYS) ...@@ -906,6 +949,8 @@ TEST_F_SIGNAL(precedence, trap_is_second, SIGSYS)
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow); ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
ASSERT_EQ(0, ret); ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log);
ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace); ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
ASSERT_EQ(0, ret); ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error); ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
...@@ -931,6 +976,8 @@ TEST_F_SIGNAL(precedence, trap_is_second_in_any_order, SIGSYS) ...@@ -931,6 +976,8 @@ TEST_F_SIGNAL(precedence, trap_is_second_in_any_order, SIGSYS)
ASSERT_EQ(0, ret); ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trap); ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trap);
ASSERT_EQ(0, ret); ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log);
ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace); ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
ASSERT_EQ(0, ret); ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error); ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
...@@ -952,6 +999,8 @@ TEST_F(precedence, errno_is_third) ...@@ -952,6 +999,8 @@ TEST_F(precedence, errno_is_third)
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow); ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
ASSERT_EQ(0, ret); ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log);
ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace); ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
ASSERT_EQ(0, ret); ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error); ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
...@@ -970,6 +1019,8 @@ TEST_F(precedence, errno_is_third_in_any_order) ...@@ -970,6 +1019,8 @@ TEST_F(precedence, errno_is_third_in_any_order)
ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
ASSERT_EQ(0, ret); ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log);
ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error); ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
ASSERT_EQ(0, ret); ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace); ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
...@@ -992,6 +1043,8 @@ TEST_F(precedence, trace_is_fourth) ...@@ -992,6 +1043,8 @@ TEST_F(precedence, trace_is_fourth)
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow); ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
ASSERT_EQ(0, ret); ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log);
ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace); ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
ASSERT_EQ(0, ret); ASSERT_EQ(0, ret);
/* Should work just fine. */ /* Should work just fine. */
...@@ -1013,12 +1066,54 @@ TEST_F(precedence, trace_is_fourth_in_any_order) ...@@ -1013,12 +1066,54 @@ TEST_F(precedence, trace_is_fourth_in_any_order)
ASSERT_EQ(0, ret); ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow); ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
ASSERT_EQ(0, ret); ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log);
ASSERT_EQ(0, ret);
/* Should work just fine. */ /* Should work just fine. */
EXPECT_EQ(parent, syscall(__NR_getppid)); EXPECT_EQ(parent, syscall(__NR_getppid));
/* No ptracer */ /* No ptracer */
EXPECT_EQ(-1, syscall(__NR_getpid)); EXPECT_EQ(-1, syscall(__NR_getpid));
} }
TEST_F(precedence, log_is_fifth)
{
pid_t mypid, parent;
long ret;
mypid = getpid();
parent = getppid();
ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log);
ASSERT_EQ(0, ret);
/* Should work just fine. */
EXPECT_EQ(parent, syscall(__NR_getppid));
/* Should also work just fine */
EXPECT_EQ(mypid, syscall(__NR_getpid));
}
TEST_F(precedence, log_is_fifth_in_any_order)
{
pid_t mypid, parent;
long ret;
mypid = getpid();
parent = getppid();
ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->log);
ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
ASSERT_EQ(0, ret);
/* Should work just fine. */
EXPECT_EQ(parent, syscall(__NR_getppid));
/* Should also work just fine */
EXPECT_EQ(mypid, syscall(__NR_getpid));
}
#ifndef PTRACE_O_TRACESECCOMP #ifndef PTRACE_O_TRACESECCOMP
#define PTRACE_O_TRACESECCOMP 0x00000080 #define PTRACE_O_TRACESECCOMP 0x00000080
#endif #endif
...@@ -2603,7 +2698,7 @@ TEST(get_action_avail) ...@@ -2603,7 +2698,7 @@ TEST(get_action_avail)
{ {
__u32 actions[] = { SECCOMP_RET_KILL, SECCOMP_RET_TRAP, __u32 actions[] = { SECCOMP_RET_KILL, SECCOMP_RET_TRAP,
SECCOMP_RET_ERRNO, SECCOMP_RET_TRACE, SECCOMP_RET_ERRNO, SECCOMP_RET_TRACE,
SECCOMP_RET_ALLOW }; SECCOMP_RET_LOG, SECCOMP_RET_ALLOW };
__u32 unknown_action = 0x10000000U; __u32 unknown_action = 0x10000000U;
int i; int i;
long ret; long ret;
...@@ -2640,6 +2735,7 @@ TEST(get_action_avail) ...@@ -2640,6 +2735,7 @@ TEST(get_action_avail)
* - 64-bit arg prodding * - 64-bit arg prodding
* - arch value testing (x86 modes especially) * - arch value testing (x86 modes especially)
* - verify that FILTER_FLAG_LOG filters generate log messages * - verify that FILTER_FLAG_LOG filters generate log messages
* - verify that RET_LOG generates log messages
* - ... * - ...
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment