do not allow open with write permission

This commit is contained in:
virusdefender 2017-05-28 01:29:19 +08:00
parent cb9f0ab4c1
commit 6f2126c50b
7 changed files with 68 additions and 41 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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) {

View File

@ -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

View File

@ -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)])

View File

@ -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)

View File

@ -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;
}