|
Message-Id: <1458788042-26173-3-git-send-email-mic@digikod.net> Date: Thu, 24 Mar 2016 03:53:56 +0100 From: Mickaël Salaün <mic@...ikod.net> To: linux-security-module@...r.kernel.org Cc: Mickaël Salaün <mic@...ikod.net>, Andreas Gruenbacher <agruenba@...hat.com>, Andy Lutomirski <luto@...capital.net>, Andy Lutomirski <luto@...nel.org>, Arnd Bergmann <arnd@...db.de>, Casey Schaufler <casey@...aufler-ca.com>, Daniel Borkmann <daniel@...earbox.net>, David Drysdale <drysdale@...gle.com>, Eric Paris <eparis@...hat.com>, James Morris <james.l.morris@...cle.com>, Jeff Dike <jdike@...toit.com>, Julien Tinnes <jln@...gle.com>, Kees Cook <keescook@...omium.org>, Michael Kerrisk <mtk@...7.org>, Paul Moore <pmoore@...hat.com>, Richard Weinberger <richard@....at>, "Serge E . Hallyn" <serge@...lyn.com>, Stephen Smalley <sds@...ho.nsa.gov>, Tetsuo Handa <penguin-kernel@...ove.SAKURA.ne.jp>, Will Drewry <wad@...omium.org>, linux-api@...r.kernel.org, kernel-hardening@...ts.openwall.com Subject: [RFC v1 11/17] selftest/seccomp: Add argeval_open_whitelist test Test a basic sandbox adding a checker group and using it for path filtering. Signed-off-by: Mickaël Salaün <mic@...ikod.net> Cc: Andy Lutomirski <luto@...nel.org> Cc: Kees Cook <keescook@...omium.org> Cc: Paul Moore <pmoore@...hat.com> Cc: Will Drewry <wad@...omium.org> --- tools/testing/selftests/seccomp/seccomp_bpf.c | 114 ++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c index 8b1a6bfc64a1..49c5d39c30a4 100644 --- a/tools/testing/selftests/seccomp/seccomp_bpf.c +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c @@ -2237,6 +2237,120 @@ TEST(field_is_valid_syscall) EXPECT_EQ(-1, syscall(__NR_getpid)); EXPECT_EQ(EINVAL, errno); } + +#define PATH_DEV_NULL "/dev/null" +#define PATH_DEV_ZERO "/dev/zero" + +/* The sandbox0 allow opening only @allowed_path */ +void apply_sandbox0(struct __test_metadata *_metadata, const char *allowed_path) +{ + struct sock_filter filter0[] = { + /* Only care about open(2) */ + BPF_STMT(BPF_LD|BPF_W|BPF_ABS, + offsetof(struct seccomp_data, nr)), + BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_open, 0, 1), + /* Check the objects of group 5 matching the first argument */ + BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ARGEVAL | 1 << 8 | 5), + BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW), + }; + struct sock_fprog prog0 = { + .len = (unsigned short)ARRAY_SIZE(filter0), + .filter = filter0, + }; + struct sock_filter filter1[] = { + /* Does not need to check for arch nor syscall number because + * of the @checker_group check + */ + BPF_STMT(BPF_LD|BPF_W|BPF_ABS, + offsetof(struct seccomp_data, checker_group)), + BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 5, 1, 0), + BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW), + /* Kill if not a valid syscall (unknown open‽) */ + BPF_STMT(BPF_LD|BPF_W|BPF_ABS, + offsetof(struct seccomp_data, is_valid_syscall)), + BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 1, 1, 0), + BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL), + /* Denied access if the first argument was not validated by the + * checker. + */ + BPF_STMT(BPF_LD|BPF_W|BPF_ABS, match_arg(0)), + /* Match the first two checkers, if any */ + BPF_JUMP(BPF_JMP|BPF_JSET|BPF_K, 3, 0, 1), + BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW), + /* Use an impossible errno value to ensure it comes from our + * filter (should be EACCES most of the time). + */ + BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ERRNO | E2BIG), + }; + struct sock_fprog prog1 = { + .len = (unsigned short)ARRAY_SIZE(filter1), + .filter = filter1, + }; + struct seccomp_object_path path0 = SECCOMP_MAKE_PATH_DENTRY(allowed_path); + struct seccomp_checker checker0[] = { + SECCOMP_MAKE_OBJ_PATH(FS_LITERAL, &path0), + }; + /* Group 5 */ + struct seccomp_checker_group checker_group0 = { + .version = 1, + .id = 5, + .len = ARRAY_SIZE(checker0), + .checkers = &checker0, + }; + + /* Set up the test sandbox */ + ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { + TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!"); + } + /* Load the path checkers */ + EXPECT_EQ(0, seccomp(SECCOMP_ADD_CHECKER_GROUP, 0, &checker_group0)) { + TH_LOG("Failed to add checker group!"); + } + /* Load filters in reverse order */ + EXPECT_EQ(0, seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog1)) { + TH_LOG("Failed to install filter!"); + } + EXPECT_EQ(0, seccomp(SECCOMP_SET_MODE_FILTER, + SECCOMP_FILTER_FLAG_TSYNC, &prog0)) { + TH_LOG("Failed to install filter!"); + } +} + +TEST(argeval_open_whitelist) +{ + int fd; + + /* Validate the first test file */ + fd = open(PATH_DEV_ZERO, O_RDONLY); + EXPECT_NE(-1, fd) { + TH_LOG("Failed to open " PATH_DEV_ZERO); + } + close(fd); + + /* Validate the second test file */ + fd = open(PATH_DEV_NULL, O_RDONLY); + EXPECT_NE(-1, fd) { + TH_LOG("Failed to open " PATH_DEV_NULL); + } + close(fd); + + apply_sandbox0(_metadata, PATH_DEV_ZERO); + + /* Allowed file */ + fd = open(PATH_DEV_ZERO, O_RDONLY); + EXPECT_NE(-1, fd) { + TH_LOG("Failed to open " PATH_DEV_ZERO); + } + close(fd); + + /* Denied file (by the filter) */ + fd = open(PATH_DEV_NULL, O_RDONLY); + EXPECT_EQ(-1, fd) { + TH_LOG("Could open " PATH_DEV_NULL); + } + EXPECT_EQ(E2BIG, errno); + close(fd); +} #endif /* SECCOMP_DATA_ARGEVAL_PRESENT */ /* -- 2.8.0.rc3
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.