* [PATCH 0/2] Support auditing while still allowing a syscall
@ 2017-01-02 17:26 Tyler Hicks
2017-01-02 17:26 ` [PATCH 1/2] seccomp: Create an action to audit before allowing Tyler Hicks
2017-01-02 17:26 ` [PATCH 2/2] seccomp: Add tests for SECCOMP_RET_AUDIT Tyler Hicks
0 siblings, 2 replies; 4+ messages in thread
From: Tyler Hicks @ 2017-01-02 17:26 UTC (permalink / raw)
To: Paul Moore, Eric Paris, Kees Cook, Andy Lutomirski, Will Drewry
Cc: linux-audit, linux-kernel
Allow application authors to opt into auditing a syscall before allowing it.
This differs slightly from SECCOMP_RET_ALLOW in that an audit message is
generated for the syscall.
It can be useful when initially setting up a seccomp sandbox for your
application if you set the default action to audit instead of, for example,
kill when the application makes a restricted system call. The application
author can easily compile a list of syscalls that need to be allowed instead of
iteratively building the application, testing the application, updating the
filter, and repeating until all appropriate system calls have been allowed.
This patch set depends on the following patch set:
https://lkml.kernel.org/r/1483375990-14948-1-git-send-email-tyhicks@canonical.com
(At least, I hope it shows up at that link soon because marc.info doesn't yet
know of the message-id.)
The corresponding libseccomp changes can be found here:
https://github.com/seccomp/libseccomp/pull/64
Thanks!
Tyler
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/2] seccomp: Create an action to audit before allowing
2017-01-02 17:26 [PATCH 0/2] Support auditing while still allowing a syscall Tyler Hicks
@ 2017-01-02 17:26 ` Tyler Hicks
2017-01-02 20:32 ` kbuild test robot
2017-01-02 17:26 ` [PATCH 2/2] seccomp: Add tests for SECCOMP_RET_AUDIT Tyler Hicks
1 sibling, 1 reply; 4+ messages in thread
From: Tyler Hicks @ 2017-01-02 17:26 UTC (permalink / raw)
To: Paul Moore, Eric Paris, Kees Cook, Andy Lutomirski, Will Drewry
Cc: linux-audit, linux-kernel
Add a new action, SECCOMP_RET_AUDIT, which is identical to
SECCOMP_RET_ALLOW with the exception that an audit message is logged
rather than quietly allowing the syscall.
This can be very useful when initially developing a seccomp filter for
an application because the list of syscalls needed, which aren't marked
for SECCOMP_RET_ALLOW, can be easily lifted from the audit log reports
after exercising the application. 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.
SECCOMP_RET_AUDIT is considered to be slightly more restrictive than
SECCOMP_RET_ALLOW. The reason is because 'audit before allowing' is more
restrictive than 'silently allowing'.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
---
Documentation/prctl/seccomp_filter.txt | 4 ++++
include/uapi/linux/seccomp.h | 1 +
kernel/seccomp.c | 4 ++++
3 files changed, 9 insertions(+)
diff --git a/Documentation/prctl/seccomp_filter.txt b/Documentation/prctl/seccomp_filter.txt
index 1e469ef..61169d3 100644
--- a/Documentation/prctl/seccomp_filter.txt
+++ b/Documentation/prctl/seccomp_filter.txt
@@ -138,6 +138,10 @@ SECCOMP_RET_TRACE:
allow use of ptrace, even of other sandboxed processes, without
extreme care; ptracers can use this mechanism to escape.)
+SECCOMP_RET_AUDIT:
+ Results in the system call being executed after an audit log record is
+ emitted.
+
SECCOMP_RET_ALLOW:
Results in the system call being executed.
diff --git a/include/uapi/linux/seccomp.h b/include/uapi/linux/seccomp.h
index 0f238a4..551f099 100644
--- a/include/uapi/linux/seccomp.h
+++ b/include/uapi/linux/seccomp.h
@@ -29,6 +29,7 @@
#define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */
#define SECCOMP_RET_ERRNO 0x00050000U /* returns an errno */
#define SECCOMP_RET_TRACE 0x7ff00000U /* pass to a tracer or disallow */
+#define SECCOMP_RET_AUDIT 0x7ffe0000U /* allow with an audit message */
#define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */
/* Masks for the return value sections. */
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index e99c566..2c0ed54 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -632,6 +632,10 @@ static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd,
return 0;
+ case SECCOMP_RET_AUDIT:
+ audit_seccomp_common(this_syscall, action);
+ return 0;
+
case SECCOMP_RET_ALLOW:
return 0;
--
2.7.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/2] seccomp: Add tests for SECCOMP_RET_AUDIT
2017-01-02 17:26 [PATCH 0/2] Support auditing while still allowing a syscall Tyler Hicks
2017-01-02 17:26 ` [PATCH 1/2] seccomp: Create an action to audit before allowing Tyler Hicks
@ 2017-01-02 17:26 ` Tyler Hicks
1 sibling, 0 replies; 4+ messages in thread
From: Tyler Hicks @ 2017-01-02 17:26 UTC (permalink / raw)
To: Paul Moore, Eric Paris, Kees Cook, Andy Lutomirski, Will Drewry
Cc: linux-audit, linux-kernel
Extend the kernel selftests for seccomp to test the newly added
SECCOMP_RET_AUDIT action. The added tests follow the example of existing
tests.
Unfortunately, the tests are not capable of inspecting the audit log to
verify that an audit message was emitted.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
---
tools/testing/selftests/seccomp/seccomp_bpf.c | 94 +++++++++++++++++++++++++++
1 file changed, 94 insertions(+)
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c
index 03f1fa4..9cff9fa 100644
--- a/tools/testing/selftests/seccomp/seccomp_bpf.c
+++ b/tools/testing/selftests/seccomp/seccomp_bpf.c
@@ -87,6 +87,10 @@ struct seccomp_data {
};
#endif
+#ifndef SECCOMP_RET_AUDIT
+#define SECCOMP_RET_AUDIT 0x7ffe0000U /* allow with an audit message */
+#endif
+
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define syscall_arg(_n) (offsetof(struct seccomp_data, args[_n]))
#elif __BYTE_ORDER == __BIG_ENDIAN
@@ -342,6 +346,28 @@ TEST(empty_prog)
EXPECT_EQ(EINVAL, errno);
}
+TEST(AUDIT_all)
+{
+ struct sock_filter filter[] = {
+ BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_AUDIT),
+ };
+ 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 audited (no check for auditing) */
+ EXPECT_EQ(parent, syscall(__NR_getppid));
+}
+
TEST_SIGNAL(unknown_ret_is_kill_inside, SIGSYS)
{
struct sock_filter filter[] = {
@@ -735,6 +761,7 @@ TEST_F(TRAP, handler)
FIXTURE_DATA(precedence) {
struct sock_fprog allow;
+ struct sock_fprog audit;
struct sock_fprog trace;
struct sock_fprog error;
struct sock_fprog trap;
@@ -746,6 +773,13 @@ FIXTURE_SETUP(precedence)
struct sock_filter allow_insns[] = {
BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
};
+ struct sock_filter audit_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_AUDIT),
+ };
struct sock_filter trace_insns[] = {
BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
offsetof(struct seccomp_data, nr)),
@@ -782,6 +816,7 @@ FIXTURE_SETUP(precedence)
memcpy(self->_x.filter, &_x##_insns, sizeof(_x##_insns)); \
self->_x.len = (unsigned short)ARRAY_SIZE(_x##_insns)
FILTER_ALLOC(allow);
+ FILTER_ALLOC(audit);
FILTER_ALLOC(trace);
FILTER_ALLOC(error);
FILTER_ALLOC(trap);
@@ -792,6 +827,7 @@ FIXTURE_TEARDOWN(precedence)
{
#define FILTER_FREE(_x) if (self->_x.filter) free(self->_x.filter)
FILTER_FREE(allow);
+ FILTER_FREE(audit);
FILTER_FREE(trace);
FILTER_FREE(error);
FILTER_FREE(trap);
@@ -809,6 +845,8 @@ TEST_F(precedence, allow_ok)
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
ASSERT_EQ(0, ret);
+ ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->audit);
+ ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
@@ -833,6 +871,8 @@ TEST_F_SIGNAL(precedence, kill_is_highest, SIGSYS)
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
ASSERT_EQ(0, ret);
+ ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->audit);
+ ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
@@ -864,6 +904,8 @@ TEST_F_SIGNAL(precedence, kill_is_highest_in_any_order, SIGSYS)
ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
ASSERT_EQ(0, ret);
+ ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->audit);
+ ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trap);
@@ -885,6 +927,8 @@ TEST_F_SIGNAL(precedence, trap_is_second, SIGSYS)
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
ASSERT_EQ(0, ret);
+ ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->audit);
+ ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
@@ -910,6 +954,8 @@ TEST_F_SIGNAL(precedence, trap_is_second_in_any_order, SIGSYS)
ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trap);
ASSERT_EQ(0, ret);
+ ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->audit);
+ ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
@@ -931,6 +977,8 @@ TEST_F(precedence, errno_is_third)
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
ASSERT_EQ(0, ret);
+ ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->audit);
+ ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
@@ -949,6 +997,8 @@ TEST_F(precedence, errno_is_third_in_any_order)
ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
ASSERT_EQ(0, ret);
+ ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->audit);
+ ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
@@ -971,6 +1021,8 @@ TEST_F(precedence, trace_is_fourth)
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
ASSERT_EQ(0, ret);
+ ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->audit);
+ ASSERT_EQ(0, ret);
ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
ASSERT_EQ(0, ret);
/* Should work just fine. */
@@ -992,12 +1044,54 @@ TEST_F(precedence, trace_is_fourth_in_any_order)
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->audit);
+ ASSERT_EQ(0, ret);
/* Should work just fine. */
EXPECT_EQ(parent, syscall(__NR_getppid));
/* No ptracer */
EXPECT_EQ(-1, syscall(__NR_getpid));
}
+TEST_F(precedence, audit_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->audit);
+ 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, audit_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->audit);
+ 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
#define PTRACE_O_TRACESECCOMP 0x00000080
#endif
--
2.7.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 1/2] seccomp: Create an action to audit before allowing
2017-01-02 17:26 ` [PATCH 1/2] seccomp: Create an action to audit before allowing Tyler Hicks
@ 2017-01-02 20:32 ` kbuild test robot
0 siblings, 0 replies; 4+ messages in thread
From: kbuild test robot @ 2017-01-02 20:32 UTC (permalink / raw)
To: Tyler Hicks
Cc: kbuild-all, Paul Moore, Eric Paris, Kees Cook, Andy Lutomirski,
Will Drewry, linux-audit, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 1341 bytes --]
Hi Tyler,
[auto build test ERROR on linus/master]
[also build test ERROR on v4.10-rc2 next-20161224]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Tyler-Hicks/seccomp-Create-an-action-to-audit-before-allowing/20170103-041342
config: i386-randconfig-x003-201701 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=i386
All errors (new ones prefixed by >>):
kernel/seccomp.c: In function '__seccomp_filter':
>> kernel/seccomp.c:634:3: error: implicit declaration of function 'audit_seccomp_common' [-Werror=implicit-function-declaration]
audit_seccomp_common(this_syscall, action);
^~~~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
vim +/audit_seccomp_common +634 kernel/seccomp.c
628 if (__seccomp_filter(this_syscall, NULL, true))
629 return -1;
630
631 return 0;
632
633 case SECCOMP_RET_AUDIT:
> 634 audit_seccomp_common(this_syscall, action);
635 return 0;
636
637 case SECCOMP_RET_ALLOW:
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 25534 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2017-01-02 20:33 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-02 17:26 [PATCH 0/2] Support auditing while still allowing a syscall Tyler Hicks
2017-01-02 17:26 ` [PATCH 1/2] seccomp: Create an action to audit before allowing Tyler Hicks
2017-01-02 20:32 ` kbuild test robot
2017-01-02 17:26 ` [PATCH 2/2] seccomp: Add tests for SECCOMP_RET_AUDIT Tyler Hicks
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).