From 850040e21d3cf9ca8d625e6dafcc5f9dab68222f Mon Sep 17 00:00:00 2001 From: zema1 Date: Tue, 29 Aug 2017 19:08:28 +0800 Subject: [PATCH 1/2] add openat seccomp rule --- src/rules/general.c | 10 +++- .../Python_and_core/testcase/seccomp/test.py | 55 +++++++++++++++++-- .../{write_file.c => write_file_open.c} | 0 tests/test_src/seccomp/write_file_openat.c | 26 +++++++++ 4 files changed, 85 insertions(+), 6 deletions(-) rename tests/test_src/seccomp/{write_file.c => write_file_open.c} (100%) create mode 100644 tests/test_src/seccomp/write_file_openat.c diff --git a/src/rules/general.c b/src/rules/general.c index 2efbd2d..82e2dca 100644 --- a/src/rules/general.c +++ b/src/rules/general.c @@ -27,13 +27,21 @@ int general_seccomp_rules(struct config *_config) { if (seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(execve), 1, SCMP_A0(SCMP_CMP_NE, (scmp_datum_t)(_config->exe_path))) != 0) { return LOAD_SECCOMP_FAILED; } - // do not allow "w" and "rw" + // do not allow "w" and "rw" using open if (seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(open), 1, SCMP_CMP(1, SCMP_CMP_MASKED_EQ, O_WRONLY, O_WRONLY)) != 0) { return LOAD_SECCOMP_FAILED; } if (seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(open), 1, SCMP_CMP(1, SCMP_CMP_MASKED_EQ, O_RDWR, O_RDWR)) != 0) { return LOAD_SECCOMP_FAILED; } + // do not allow "w" and "rw" using openat + if (seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(openat), 1, SCMP_CMP(2, SCMP_CMP_MASKED_EQ, O_WRONLY, O_WRONLY)) != 0) { + return LOAD_SECCOMP_FAILED; + } + if (seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(openat), 1, SCMP_CMP(2, SCMP_CMP_MASKED_EQ, O_RDWR, O_RDWR)) != 0) { + return LOAD_SECCOMP_FAILED; + } + if (seccomp_load(ctx) != 0) { return LOAD_SECCOMP_FAILED; } diff --git a/tests/Python_and_core/testcase/seccomp/test.py b/tests/Python_and_core/testcase/seccomp/test.py index 929c05d..8617afe 100644 --- a/tests/Python_and_core/testcase/seccomp/test.py +++ b/tests/Python_and_core/testcase/seccomp/test.py @@ -58,9 +58,9 @@ class SeccompTest(base.BaseTestCase): self.assertEqual(result["result"], _judger.RESULT_RUNTIME_ERROR) self.assertEqual(result["signal"], self.BAD_SYSTEM_CALL) - def test_write_file(self): + def test_write_file_using_open(self): config = self.base_config - config["exe_path"] = self._compile_c("write_file.c") + config["exe_path"] = self._compile_c("write_file_open.c") config["output_path"] = config["error_path"] = self.output_path() path = os.path.join(self.workspace, "file1.txt") config["args"] = [path, "w"] @@ -81,14 +81,59 @@ class SeccompTest(base.BaseTestCase): self.assertEqual(result["result"], _judger.RESULT_RUNTIME_ERROR) self.assertEqual(result["signal"], self.BAD_SYSTEM_CALL) - def test_read_write_file(self): + def test_read_write_file_using_open(self): config = self.base_config - config["exe_path"] = self._compile_c("write_file.c") + config["exe_path"] = self._compile_c("write_file_open.c") config["output_path"] = config["error_path"] = self.output_path() path = os.path.join(self.workspace, "file2.txt") config["args"] = [path, "w+"] result = _judger.run(**config) - print(result) + # without seccomp + self.assertEqual(result["result"], _judger.RESULT_SUCCESS) + self.assertEqual("", self.output_content(path)) + + # with general seccomp + config["seccomp_rule_name"] = "general" + result = _judger.run(**config) + self.assertEqual(result["result"], _judger.RESULT_RUNTIME_ERROR) + self.assertEqual(result["signal"], self.BAD_SYSTEM_CALL) + + # with c_cpp seccomp + config["seccomp_rule_name"] = "c_cpp" + result = _judger.run(**config) + self.assertEqual(result["result"], _judger.RESULT_RUNTIME_ERROR) + self.assertEqual(result["signal"], self.BAD_SYSTEM_CALL) + + def test_write_file_using_openat(self): + config = self.base_config + config["exe_path"] = self._compile_c("write_file_openat.c") + config["output_path"] = config["error_path"] = self.output_path() + path = os.path.join(self.workspace, "file3.txt") + config["args"] = [self.workspace, "file3.txt", "w"] + result = _judger.run(**config) + # without seccomp + self.assertEqual(result["result"], _judger.RESULT_SUCCESS) + self.assertEqual("", self.output_content(path)) + + # with general seccomp + config["seccomp_rule_name"] = "general" + result = _judger.run(**config) + self.assertEqual(result["result"], _judger.RESULT_RUNTIME_ERROR) + self.assertEqual(result["signal"], self.BAD_SYSTEM_CALL) + + # with c_cpp seccomp + config["seccomp_rule_name"] = "c_cpp" + result = _judger.run(**config) + self.assertEqual(result["result"], _judger.RESULT_RUNTIME_ERROR) + self.assertEqual(result["signal"], self.BAD_SYSTEM_CALL) + + def test_read_write_file_using_openat(self): + config = self.base_config + config["exe_path"] = self._compile_c("write_file_openat.c") + config["output_path"] = config["error_path"] = self.output_path() + path = os.path.join(self.workspace, "file4.txt") + config["args"] = [self.workspace, "file4.txt", "w+"] + result = _judger.run(**config) # without seccomp self.assertEqual(result["result"], _judger.RESULT_SUCCESS) self.assertEqual("", self.output_content(path)) diff --git a/tests/test_src/seccomp/write_file.c b/tests/test_src/seccomp/write_file_open.c similarity index 100% rename from tests/test_src/seccomp/write_file.c rename to tests/test_src/seccomp/write_file_open.c diff --git a/tests/test_src/seccomp/write_file_openat.c b/tests/test_src/seccomp/write_file_openat.c new file mode 100644 index 0000000..75cda60 --- /dev/null +++ b/tests/test_src/seccomp/write_file_openat.c @@ -0,0 +1,26 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + DIR *dir = opendir(argv[1]); + int dir_fd = dirfd(dir); + int flags; + if (!strcmp(argv[3], "w")) { + flags = O_WRONLY | O_CREAT; + } + else { + flags = O_RDWR | O_CREAT; + } + int fd = openat(dir_fd, argv[2], flags, 0755); + if (fd < 0) { + return errno; + } + close(fd); + return 0; +} \ No newline at end of file From e15806026b144a501a9797c0f4d2ce085ea9399d Mon Sep 17 00:00:00 2001 From: zema1 Date: Wed, 30 Aug 2017 08:46:48 +0800 Subject: [PATCH 2/2] simplify write_file_openat.c --- tests/Python_and_core/testcase/seccomp/test.py | 4 ++-- tests/test_src/seccomp/write_file_openat.c | 16 +++++----------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/tests/Python_and_core/testcase/seccomp/test.py b/tests/Python_and_core/testcase/seccomp/test.py index 8617afe..659fc29 100644 --- a/tests/Python_and_core/testcase/seccomp/test.py +++ b/tests/Python_and_core/testcase/seccomp/test.py @@ -109,7 +109,7 @@ class SeccompTest(base.BaseTestCase): config["exe_path"] = self._compile_c("write_file_openat.c") config["output_path"] = config["error_path"] = self.output_path() path = os.path.join(self.workspace, "file3.txt") - config["args"] = [self.workspace, "file3.txt", "w"] + config["args"] = [path, "w"] result = _judger.run(**config) # without seccomp self.assertEqual(result["result"], _judger.RESULT_SUCCESS) @@ -132,7 +132,7 @@ class SeccompTest(base.BaseTestCase): config["exe_path"] = self._compile_c("write_file_openat.c") config["output_path"] = config["error_path"] = self.output_path() path = os.path.join(self.workspace, "file4.txt") - config["args"] = [self.workspace, "file4.txt", "w+"] + config["args"] = [path, "w+"] result = _judger.run(**config) # without seccomp self.assertEqual(result["result"], _judger.RESULT_SUCCESS) diff --git a/tests/test_src/seccomp/write_file_openat.c b/tests/test_src/seccomp/write_file_openat.c index 75cda60..316f0b0 100644 --- a/tests/test_src/seccomp/write_file_openat.c +++ b/tests/test_src/seccomp/write_file_openat.c @@ -1,26 +1,20 @@ -#include +#include #include #include #include -#include -#include -#include -#include int main(int argc, char *argv[]) { - DIR *dir = opendir(argv[1]); - int dir_fd = dirfd(dir); int flags; - if (!strcmp(argv[3], "w")) { + if (!strcmp(argv[2], "w")) { flags = O_WRONLY | O_CREAT; } else { flags = O_RDWR | O_CREAT; } - int fd = openat(dir_fd, argv[2], flags, 0755); + int fd = openat(0, argv[1], flags, 0755); if (fd < 0) { - return errno; + return errno; } close(fd); return 0; -} \ No newline at end of file +}