From 6cdabb61ae70b21fb1a6a5feeb4034f575621812 Mon Sep 17 00:00:00 2001 From: virusdefender Date: Sun, 14 Oct 2018 17:26:37 +0800 Subject: [PATCH] try to fix permission --- Dockerfile | 2 +- server/config.py | 3 +++ server/entrypoint.sh | 15 +++++++++++++-- server/judge_client.py | 12 +++++++++--- server/server.py | 18 ++++++++++++------ 5 files changed, 38 insertions(+), 12 deletions(-) diff --git a/Dockerfile b/Dockerfile index b2a8d9b..9f7df40 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,7 @@ RUN buildDeps='software-properties-common git libtool cmake python-dev python3-p mkdir build && cd build && cmake .. && make && make install && cd ../bindings/Python && python3 setup.py install && \ apt-get purge -y --auto-remove $buildDeps && \ apt-get clean && rm -rf /var/lib/apt/lists/* && \ - mkdir -p /code && useradd -r compiler && useradd -r code + mkdir -p /code HEALTHCHECK --interval=5s --retries=3 CMD python3 /code/service.py ADD server /code diff --git a/server/config.py b/server/config.py index ed04b83..8a33406 100644 --- a/server/config.py +++ b/server/config.py @@ -16,6 +16,9 @@ RUN_GROUP_GID = grp.getgrnam("code").gr_gid COMPILER_USER_UID = pwd.getpwnam("compiler").pw_uid COMPILER_GROUP_GID = grp.getgrnam("compiler").gr_gid +SPJ_USER_UID = pwd.getpwnam("spj").pw_uid +SPJ_GROUP_GID = grp.getgrnam("spj").gr_gid + TEST_CASE_DIR = "/test_case" SPJ_SRC_DIR = "/judger/spj" SPJ_EXE_DIR = "/judger/spj" diff --git a/server/entrypoint.sh b/server/entrypoint.sh index f21250f..9460d46 100755 --- a/server/entrypoint.sh +++ b/server/entrypoint.sh @@ -1,8 +1,19 @@ #!/bin/bash +useradd -u 12001 compiler +useradd -u 12002 code +useradd -u 12003 spj +usermod -a -G code spj + rm -rf /judger/* mkdir -p /judger/run /judger/spj -chown -R compiler:compiler /judger/ -chmod -R 771 /judger/ + +chown compiler:code /judger/run +# 71[1] allow spj user to read user output +chmod 711 /judger/run + +chown compiler:spj /judger/spj +chmod 710 /judger/spj + core=$(grep --count ^processor /proc/cpuinfo) n=$(($core*2)) exec gunicorn --workers $n --threads $n --error-logfile /log/gunicorn.log --time 600 --bind 0.0.0.0:8080 server:app diff --git a/server/judge_client.py b/server/judge_client.py index 5f012d5..241bb49 100644 --- a/server/judge_client.py +++ b/server/judge_client.py @@ -6,7 +6,7 @@ from multiprocessing import Pool import psutil -from config import TEST_CASE_DIR, JUDGER_RUN_LOG_PATH, RUN_GROUP_GID, RUN_USER_UID, SPJ_EXE_DIR +from config import TEST_CASE_DIR, JUDGER_RUN_LOG_PATH, RUN_GROUP_GID, RUN_USER_UID, SPJ_EXE_DIR, SPJ_USER_UID, SPJ_GROUP_GID, RUN_GROUP_GID from exception import JudgeClientError SPJ_WA = 1 @@ -63,6 +63,12 @@ class JudgeClient(object): return output_md5, result def _spj(self, in_file_path, user_out_file_path): + # by default, submission dir is compiler:code 710, we should change it for + # spj user to read user output file + os.chown(self._submission_dir, SPJ_USER_UID, 0) + os.chmod(self._submission_dir, 0o100) + os.chown(user_out_file_path, SPJ_USER_UID, 0) + os.chmod(user_out_file_path, 0o400) command = self._spj_config["command"].format(exe_path=self._spj_exe, in_file_path=in_file_path, user_out_file_path=user_out_file_path).split(" ") @@ -81,8 +87,8 @@ class JudgeClient(object): env=["PATH=" + os.environ.get("PATH", "")], log_path=JUDGER_RUN_LOG_PATH, seccomp_rule_name=seccomp_rule_name, - uid=RUN_USER_UID, - gid=RUN_GROUP_GID) + uid=SPJ_USER_UID, + gid=SPJ_GROUP_GID) if result["result"] == _judger.RESULT_SUCCESS or \ (result["result"] == _judger.RESULT_RUNTIME_ERROR and diff --git a/server/server.py b/server/server.py index 5e70d11..e640396 100644 --- a/server/server.py +++ b/server/server.py @@ -6,7 +6,7 @@ import uuid from flask import Flask, request, Response from compiler import Compiler -from config import JUDGER_WORKSPACE_BASE, SPJ_SRC_DIR, SPJ_EXE_DIR, COMPILER_GROUP_GID +from config import JUDGER_WORKSPACE_BASE, SPJ_SRC_DIR, SPJ_EXE_DIR, COMPILER_USER_UID, SPJ_USER_UID, RUN_USER_UID, RUN_GROUP_GID from exception import TokenVerificationFailed, CompileError, SPJCompileError, JudgeClientError from judge_client import JudgeClient from utils import server_info, logger, token @@ -23,8 +23,8 @@ class InitSubmissionEnv(object): def __enter__(self): try: os.mkdir(self.path) - os.chown(self.path, 0, COMPILER_GROUP_GID) - os.chmod(self.path, 0o771) + os.chown(self.path, COMPILER_USER_UID, RUN_GROUP_GID) + os.chmod(self.path, 0o710) except Exception as e: logger.exception(e) raise JudgeClientError("failed to create runtime dir") @@ -69,6 +69,8 @@ class JudgeServer: # write source code into file with open(src_path, "w", encoding="utf-8") as f: f.write(src) + os.chown(src_path, COMPILER_USER_UID, 0) + os.chmod(src_path, 0o400) # compile source code, return exe file path exe_path = Compiler().compile(compile_config=compile_config, @@ -79,6 +81,9 @@ class JudgeServer: with open(exe_path, "w", encoding="utf-8") as f: f.write(src) + os.chown(exe_path, RUN_USER_UID, 0) + os.chmod(exe_path, 0o500) + judge_client = JudgeClient(run_config=language_config["run"], exe_path=exe_path, max_cpu_time=max_cpu_time, @@ -103,14 +108,15 @@ class JudgeServer: if not os.path.exists(spj_src_path): with open(spj_src_path, "w", encoding="utf-8") as f: f.write(src) - os.chown(spj_src_path, 0, COMPILER_GROUP_GID) - os.chmod(spj_src_path, 0o660) + os.chown(spj_src_path, COMPILER_USER_UID, 0) + os.chmod(spj_src_path, 0o400) try: exe_path = Compiler().compile(compile_config=spj_compile_config, src_path=spj_src_path, output_dir=SPJ_EXE_DIR) - os.chmod(exe_path, 0o771) + os.chown(exe_path, SPJ_USER_UID, 0) + os.chmod(exe_path, 0o500) # turn common CompileError into SPJCompileError except CompileError as e: raise SPJCompileError(e.message)