mirror of
https://github.com/QingdaoU/Judger.git
synced 2025-01-16 01:13:25 +00:00
do not allow open with write permission
This commit is contained in:
parent
cb9f0ab4c1
commit
6f2126c50b
11
runtest.sh
11
runtest.sh
@ -1,5 +1,6 @@
|
||||
apt-get update
|
||||
apt-get install cmake liblua5.3-dev
|
||||
rm -rf build && mkdir build && cd build && cmake .. && make && make install
|
||||
cd ../bindings/Python && rm -rf build && python setup.py install || exit 1
|
||||
cd ../../tests/Python_and_core && python test.py
|
||||
rm -rf build && mkdir build && cd build && cmake ..
|
||||
make || exit 1
|
||||
make install
|
||||
cd ../bindings/Python && rm -rf build
|
||||
python setup.py install || exit 1
|
||||
cd ../../tests/Python_and_core && python test.py
|
||||
|
@ -1,5 +1,8 @@
|
||||
#include <stdio.h>
|
||||
#include <seccomp.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "../runner.h"
|
||||
|
||||
@ -7,11 +10,13 @@
|
||||
int c_cpp_seccomp_rules(struct config *_config) {
|
||||
int syscalls_whitelist[] = {SCMP_SYS(read), SCMP_SYS(fstat),
|
||||
SCMP_SYS(mmap), SCMP_SYS(mprotect),
|
||||
SCMP_SYS(munmap), SCMP_SYS(open),
|
||||
SCMP_SYS(munmap), SCMP_SYS(uname),
|
||||
SCMP_SYS(arch_prctl), SCMP_SYS(brk),
|
||||
SCMP_SYS(access), SCMP_SYS(exit_group),
|
||||
SCMP_SYS(close), SCMP_SYS(readlink),
|
||||
SCMP_SYS(uname), SCMP_SYS(sysinfo)};
|
||||
SCMP_SYS(sysinfo), SCMP_SYS(write),
|
||||
SCMP_SYS(writev)};
|
||||
|
||||
int syscalls_whitelist_length = sizeof(syscalls_whitelist) / sizeof(int);
|
||||
scmp_filter_ctx ctx = NULL;
|
||||
// load seccomp rules
|
||||
@ -28,16 +33,10 @@ int c_cpp_seccomp_rules(struct config *_config) {
|
||||
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(execve), 1, SCMP_A0(SCMP_CMP_EQ, (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_ALLOW, SCMP_SYS(write), 1, SCMP_A0(SCMP_CMP_LE, 2)) != 0) {
|
||||
return LOAD_SECCOMP_FAILED;
|
||||
}
|
||||
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(writev), 1, SCMP_A0(SCMP_CMP_LE, 2)) != 0) {
|
||||
// do not allow "w" and "rw"
|
||||
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 1, SCMP_CMP(1, SCMP_CMP_MASKED_EQ, O_WRONLY | O_RDWR, 0)) != 0) {
|
||||
return LOAD_SECCOMP_FAILED;
|
||||
}
|
||||
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(lseek), 1, SCMP_A0(SCMP_CMP_LE, 2)) != 0) {
|
||||
return LOAD_SECCOMP_FAILED;
|
||||
}
|
||||
if (seccomp_load(ctx) != 0) {
|
||||
return LOAD_SECCOMP_FAILED;
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
#include <stdio.h>
|
||||
#include <seccomp.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "../runner.h"
|
||||
|
||||
@ -31,8 +34,11 @@ 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;
|
||||
}
|
||||
// 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) {
|
||||
// do not allow "w" and "rw"
|
||||
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;
|
||||
}
|
||||
if (seccomp_load(ctx) != 0) {
|
||||
|
@ -1,9 +0,0 @@
|
||||
cd ../../bindings/Python
|
||||
rm -r build
|
||||
python setup.py install
|
||||
rm -r build
|
||||
python3 setup.py install
|
||||
cd ../../tests/Python_and_core
|
||||
python test.py
|
||||
slepp 3
|
||||
python3 test.py
|
@ -16,13 +16,18 @@ class RunResult(object):
|
||||
|
||||
|
||||
class BaseTestCase(TestCase):
|
||||
BAD_SYSTEM_CALL = 31
|
||||
|
||||
def init_workspace(self, language):
|
||||
base_workspace = "/tmp"
|
||||
workspace = os.path.join(base_workspace, language)
|
||||
shutil.rmtree(workspace, ignore_errors=True)
|
||||
os.system("mkdir -p " + workspace)
|
||||
os.makedirs(workspace)
|
||||
return workspace
|
||||
|
||||
def tearDown(self):
|
||||
shutil.rmtree(self.workspace, ignore_errors=True)
|
||||
|
||||
def rand_str(self):
|
||||
return "".join([random.choice("123456789abcdef") for _ in range(12)])
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
from __future__ import print_function
|
||||
import _judger
|
||||
import signal
|
||||
import shutil
|
||||
import os
|
||||
|
||||
from .. import base
|
||||
@ -17,7 +18,6 @@ class SeccompTest(base.BaseTestCase):
|
||||
|
||||
def test_fork(self):
|
||||
config = self.base_config
|
||||
config["max_memory"] = 1024 * 1024 * 1024
|
||||
config["exe_path"] = self._compile_c("fork.c")
|
||||
config["output_path"] = config["error_path"] = self.output_path()
|
||||
result = _judger.run(**config)
|
||||
@ -29,17 +29,16 @@ class SeccompTest(base.BaseTestCase):
|
||||
config["seccomp_rule_name"] = "general"
|
||||
result = _judger.run(**config)
|
||||
self.assertEqual(result["result"], _judger.RESULT_RUNTIME_ERROR)
|
||||
self.assertEqual(result["signal"], 31)
|
||||
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"], 31)
|
||||
self.assertEqual(result["signal"], self.BAD_SYSTEM_CALL)
|
||||
|
||||
def test_execve(self):
|
||||
config = self.base_config
|
||||
config["max_memory"] = 1024 * 1024 * 1024
|
||||
config["exe_path"] = self._compile_c("execve.c")
|
||||
config["output_path"] = config["error_path"] = self.output_path()
|
||||
result = _judger.run(**config)
|
||||
@ -51,35 +50,60 @@ class SeccompTest(base.BaseTestCase):
|
||||
config["seccomp_rule_name"] = "general"
|
||||
result = _judger.run(**config)
|
||||
self.assertEqual(result["result"], _judger.RESULT_RUNTIME_ERROR)
|
||||
self.assertEqual(result["signal"], 31)
|
||||
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"], 31)
|
||||
self.assertEqual(result["signal"], self.BAD_SYSTEM_CALL)
|
||||
|
||||
def test_write_file(self):
|
||||
config = self.base_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()
|
||||
path = os.path.join(self.workspace, "file1.txt")
|
||||
config["args"] = [path, "w"]
|
||||
result = _judger.run(**config)
|
||||
# without seccomp
|
||||
self.assertEqual(result["result"], _judger.RESULT_SUCCESS)
|
||||
self.assertEqual("test", self.output_content("/tmp/fffffffffffffile.txt"))
|
||||
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"], 31)
|
||||
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"], 31)
|
||||
self.assertEqual(result["signal"], self.BAD_SYSTEM_CALL)
|
||||
|
||||
def test_read_write_file(self):
|
||||
config = self.base_config
|
||||
config["exe_path"] = self._compile_c("write_file.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_sysinfo(self):
|
||||
config = self.base_config
|
||||
@ -87,3 +111,4 @@ class SeccompTest(base.BaseTestCase):
|
||||
result = _judger.run(**config)
|
||||
|
||||
self.assertEqual(result["result"], _judger.RESULT_SUCCESS)
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
#include <stdio.h>
|
||||
int main()
|
||||
#include <errno.h>
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FILE *f = fopen("/tmp/fffffffffffffile.txt", "w");
|
||||
FILE *f = fopen(argv[1], argv[2]);
|
||||
if (f == NULL) {
|
||||
return 1;
|
||||
return errno;
|
||||
}
|
||||
fprintf(f, "%s", "test");
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user