diff --git a/src/child.c b/src/child.c index 6c3a9f0..a7b6bbf 100644 --- a/src/child.c +++ b/src/child.c @@ -137,6 +137,11 @@ int child_process(FILE *log_fp, struct config *_config) { CHILD_ERROR_EXIT(LOAD_SECCOMP_FAILED); } } + else if (strcmp("general", _config->seccomp_rule_name) == 0) { + if (general_seccomp_rules(_config) != SUCCESS ) { + CHILD_ERROR_EXIT(LOAD_SECCOMP_FAILED); + } + } // other rules else { // rule does not exist diff --git a/src/rules/general.c b/src/rules/general.c new file mode 100644 index 0000000..4fdad67 --- /dev/null +++ b/src/rules/general.c @@ -0,0 +1,35 @@ +#include +#include + +#include "../runner.h" + + +int general_seccomp_rules(struct config *_config) { + int syscalls_blacklist[] = {SCMP_SYS(socket), SCMP_SYS(clone), + SCMP_SYS(fork)}; + int syscalls_blacklist_length = sizeof(syscalls_blacklist) / sizeof(int); + scmp_filter_ctx ctx = NULL; + // load seccomp rules + ctx = seccomp_init(SCMP_ACT_ALLOW); + if (!ctx) { + return LOAD_SECCOMP_FAILED; + } + for (int i = 0; i < syscalls_blacklist_length; i++) { + if (seccomp_rule_add(ctx, SCMP_ACT_KILL, syscalls_blacklist[i], 0) != 0) { + return LOAD_SECCOMP_FAILED; + } + } + // add extra rule for execve + 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; + } + // only fd 0 1 2 are allowed + if (seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(write), 1, SCMP_A0(SCMP_CMP_GT, 2)) != 0) { + return LOAD_SECCOMP_FAILED; + } + if (seccomp_load(ctx) != 0) { + return LOAD_SECCOMP_FAILED; + } + seccomp_release(ctx); + return 0; +} \ No newline at end of file diff --git a/src/rules/seccomp_rules.h b/src/rules/seccomp_rules.h index be61cd0..7c3f55a 100644 --- a/src/rules/seccomp_rules.h +++ b/src/rules/seccomp_rules.h @@ -3,5 +3,6 @@ #include "../runner.h" int c_cpp_seccomp_rules(struct config *_config); +int general_seccomp_rules(struct config *_config); #endif //JUDGER_SECCOMP_RULES_H diff --git a/tests/testcase/seccomp/test.py b/tests/testcase/seccomp/test.py index 075e215..503188e 100644 --- a/tests/testcase/seccomp/test.py +++ b/tests/testcase/seccomp/test.py @@ -39,10 +39,17 @@ class SeccompTest(base.BaseTestCase): # without seccomp self.assertEqual(result["result"], _judger.RESULT_SUCCESS) - # with seccomp + # with general seccomp + config["seccomp_rule_name"] = "general" + result = _judger.run(**config) + self.assertEqual(result["result"], _judger.RESULT_RUNTIME_ERROR) + self.assertEqual(result["signal"], 31) + + # 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"], 31) def test_execve(self): config = self.config @@ -54,7 +61,36 @@ class SeccompTest(base.BaseTestCase): self.assertEqual(result["result"], _judger.RESULT_SUCCESS) self.assertEqual("Helloworld\n", self.output_content(config["output_path"])) - # with seccomp + # with general seccomp + config["seccomp_rule_name"] = "general" + result = _judger.run(**config) + self.assertEqual(result["result"], _judger.RESULT_RUNTIME_ERROR) + self.assertEqual(result["signal"], 31) + + # 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"], 31) + + def test_write_file(self): + config = self.config + config["max_memory"] = 1024 * 1024 * 1024 + config["exe_path"] = self._compile_c("write_file.c") + config["output_path"] = config["error_path"] = self.output_path() + result = _judger.run(**config) + # without seccomp + self.assertEqual(result["result"], _judger.RESULT_SUCCESS) + self.assertEqual("test", self.output_content("/tmp/fffffffffffffile.txt")) + + # with general seccomp + config["seccomp_rule_name"] = "general" + result = _judger.run(**config) + self.assertEqual(result["result"], _judger.RESULT_RUNTIME_ERROR) + self.assertEqual(result["signal"], 31) + + # 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"], 31) diff --git a/tests/testcase/seccomp/write_file.c b/tests/testcase/seccomp/write_file.c new file mode 100644 index 0000000..6e472d1 --- /dev/null +++ b/tests/testcase/seccomp/write_file.c @@ -0,0 +1,10 @@ +#include +int main() +{ + FILE *f = fopen("/tmp/fffffffffffffile.txt", "w"); + if (f == NULL) { + return 1; + } + fprintf(f, "%s", "test"); + return 0; +} \ No newline at end of file