| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795 |
- #ifdef __x86_64__
- typedef unsigned long long int reg_val_t;
- #define REG_SYSCALL orig_rax
- #define REG_RET rax
- #define REG_ARG0 rdi
- #define REG_ARG1 rsi
- #define REG_ARG2 rdx
- #define REG_ARG3 rcx
- #else
- typedef long int reg_val_t;
- #define REG_SYSCALL orig_eax
- #define REG_RET eax
- #define REG_ARG0 ebx
- #define REG_ARG1 ecx
- #define REG_ARG2 edx
- #define REG_ARG3 esx
- #endif
- const size_t MaxPathLen = 200;
- set<string> writable_file_name_set;
- set<string> readable_file_name_set;
- set<string> statable_file_name_set;
- set<string> soft_ban_file_name_set;
- int syscall_max_cnt[1000];
- bool syscall_should_soft_ban[1000];
- string basename(const string &path) {
- size_t p = path.rfind('/');
- if (p == string::npos) {
- return path;
- } else {
- return path.substr(p + 1);
- }
- }
- string dirname(const string &path) {
- size_t p = path.rfind('/');
- if (p == string::npos) {
- return "";
- } else {
- return path.substr(0, p);
- }
- }
- string getcwdp(pid_t pid) {
- char s[20];
- char cwd[MaxPathLen + 1];
- if (pid != 0) {
- sprintf(s, "/proc/%lld/cwd", (long long int)pid);
- } else {
- sprintf(s, "/proc/self/cwd");
- }
- int l = readlink(s, cwd, MaxPathLen);
- if (l == -1) {
- return "";
- }
- cwd[l] = '\0';
- return cwd;
- }
- string abspath(pid_t pid, const string &path) {
- if (path.size() > MaxPathLen) {
- return "";
- }
- if (path.empty()) {
- return path;
- }
- string s;
- string b;
- size_t st;
- if (path[0] == '/') {
- s = "/";
- st = 1;
- } else {
- s = getcwdp(pid) + "/";
- st = 0;
- }
- for (size_t i = st; i < path.size(); i++) {
- b += path[i];
- if (path[i] == '/') {
- if (b == "../" && !s.empty()) {
- if (s == "./") {
- s = "../";
- } else if (s != "/") {
- size_t p = s.size() - 1;
- while (p > 0 && s[p - 1] != '/') {
- p--;
- }
- if (s.size() - p == 3 && s[p] == '.' && s[p + 1] == '.' && s[p + 2] == '/') {
- s += b;
- } else {
- s.resize(p);
- }
- }
- } else if (b != "./" && b != "/") {
- s += b;
- }
- b.clear();
- }
- }
- if (b == ".." && !s.empty()) {
- if (s == "./") {
- s = "..";
- } else if (s != "/") {
- size_t p = s.size() - 1;
- while (p > 0 && s[p - 1] != '/') {
- p--;
- }
- if (s.size() - p == 3 && s[p] == '.' && s[p + 1] == '.' && s[p + 2] == '/') {
- s += b;
- } else {
- s.resize(p);
- }
- }
- } else if (b != ".") {
- s += b;
- }
- if (s.size() >= 2 && s[s.size() - 1] == '/') {
- s.resize(s.size() - 1);
- }
- return s;
- }
- string realpath(const string &path) {
- char real[PATH_MAX + 1] = {};
- if (realpath(path.c_str(), real) == NULL) {
- return "";
- }
- return real;
- }
- inline bool is_in_set_smart(string name, const set<string> &s) {
- if (name.size() > MaxPathLen) {
- return false;
- }
- if (s.count(name)) {
- return true;
- }
- for (size_t i = 0; i + 1 < name.size(); i++) {
- if ((i == 0 || name[i - 1] == '/') && name[i] == '.' && name[i + 1] == '.' && (i + 2 == name.size() || name[i + 2] == '.')) {
- return false;
- }
- }
- int level;
- for (level = 0; !name.empty(); name = dirname(name), level++) {
- if (level == 1 && s.count(name + "/*")) {
- return true;
- }
- if (s.count(name + "/")) {
- return true;
- }
- }
- if (level == 1 && s.count("/*")) {
- return true;
- }
- if (s.count("/")) {
- return true;
- }
- return false;
- }
- inline bool is_writable_file(string name) {
- if (name == "/") {
- return writable_file_name_set.count("system_root");
- }
- return is_in_set_smart(name, writable_file_name_set) || is_in_set_smart(realpath(name), readable_file_name_set);
- }
- inline bool is_readable_file(const string &name) {
- if (is_writable_file(name)) {
- return true;
- }
- if (name == "/") {
- return readable_file_name_set.count("system_root");
- }
- return is_in_set_smart(name, readable_file_name_set) || is_in_set_smart(realpath(name), readable_file_name_set);
- }
- inline bool is_statable_file(const string &name) {
- if (is_readable_file(name)) {
- return true;
- }
- if (name == "/") {
- return statable_file_name_set.count("system_root");
- }
- return is_in_set_smart(name, statable_file_name_set) || is_in_set_smart(realpath(name), statable_file_name_set);
- }
- inline bool is_soft_ban_file(const string &name) {
- if (name == "/") {
- return soft_ban_file_name_set.count("system_root");
- }
- return is_in_set_smart(name, soft_ban_file_name_set) || is_in_set_smart(realpath(name), soft_ban_file_name_set);
- }
- #ifdef __x86_64__
- int syscall_max_cnt_list_default[][2] = {
- {__NR_read , -1},
- {__NR_write , -1},
- {__NR_readv , -1},
- {__NR_writev , -1},
- {__NR_open , -1},
- {__NR_unlink , -1},
- {__NR_close , -1},
- {__NR_readlink , -1},
- {__NR_openat , -1},
- {__NR_unlinkat , -1},
- {__NR_readlinkat , -1},
- {__NR_stat , -1},
- {__NR_fstat , -1},
- {__NR_lstat , -1},
- {__NR_lseek , -1},
- {__NR_access , -1},
- {__NR_dup , -1},
- {__NR_dup2 , -1},
- {__NR_dup3 , -1},
- {__NR_ioctl , -1},
- {__NR_fcntl , -1},
- {__NR_mmap , -1},
- {__NR_mprotect , -1},
- {__NR_munmap , -1},
- {__NR_brk , -1},
- {__NR_mremap , -1},
- {__NR_msync , -1},
- {__NR_mincore , -1},
- {__NR_madvise , -1},
-
- {__NR_rt_sigaction , -1},
- {__NR_rt_sigprocmask, -1},
- {__NR_rt_sigreturn , -1},
- {__NR_rt_sigpending , -1},
- {__NR_sigaltstack , -1},
- {__NR_getcwd , -1},
- {__NR_exit , -1},
- {__NR_exit_group , -1},
- {__NR_arch_prctl , -1},
- {__NR_gettimeofday , -1},
- {__NR_getrlimit , -1},
- {__NR_getrusage , -1},
- {__NR_times , -1},
- {__NR_time , -1},
- {__NR_clock_gettime , -1},
- {__NR_restart_syscall, -1},
- {__NR_set_tid_address, -1},
- {__NR_set_robust_list, -1},
- {__NR_prlimit64 , -1},
- {__NR_futex , -1},
- {-1 , -1}
- };
- int syscall_soft_ban_list_default[] = {
- -1
- };
- const char *readable_file_name_list_default[] = {
- "/etc/ld.so.nohwcap",
- "/etc/ld.so.preload",
- "/etc/ld.so.cache",
- "/lib/x86_64-linux-gnu/",
- "/usr/lib/x86_64-linux-gnu/",
- "/usr/lib/locale/locale-archive",
- "/proc/self/exe",
- "/etc/timezone",
- "/usr/share/zoneinfo/",
- "/dev/random",
- "/dev/urandom",
- "/proc/meminfo",
- "/etc/localtime",
- "/proc/self/environ",
- "/proc/self/cmdline",
- NULL
- };
- #else
- #error T_T
- #endif
- void add_file_permission(const string &file_name, char mode) {
- if (mode == 'w') {
- writable_file_name_set.insert(file_name);
- } else if (mode == 'r') {
- readable_file_name_set.insert(file_name);
- } else if (mode == 's') {
- statable_file_name_set.insert(file_name);
- }
- for (string name = dirname(file_name); !name.empty(); name = dirname(name)) {
- statable_file_name_set.insert(name);
- }
- }
- void init_conf(const RunProgramConfig &config) {
- for (int i = 0; syscall_max_cnt_list_default[i][0] != -1; i++) {
- syscall_max_cnt[syscall_max_cnt_list_default[i][0]] = syscall_max_cnt_list_default[i][1];
- }
- for (int i = 0; syscall_soft_ban_list_default[i] != -1; i++) {
- syscall_should_soft_ban[syscall_soft_ban_list_default[i]] = true;
- }
- for (int i = 0; readable_file_name_list_default[i]; i++) {
- readable_file_name_set.insert(readable_file_name_list_default[i]);
- }
- statable_file_name_set.insert(config.work_path + "/");
- if (config.type != "java8" && config.type != "java11") {
- add_file_permission(config.program_name, 'r');
- } else {
- int p = config.program_name.find('.');
- if (p == string::npos) {
- readable_file_name_set.insert(config.work_path + "/");
- } else {
- readable_file_name_set.insert(config.work_path + "/" + config.program_name.substr(0, p) + "/");
- }
- }
- add_file_permission(config.work_path, 'r');
- for (vector<string>::const_iterator it = config.extra_readable_files.begin(); it != config.extra_readable_files.end(); it++) {
- add_file_permission(*it, 'r');
- }
- for (vector<string>::const_iterator it = config.extra_writable_files.begin(); it != config.extra_writable_files.end(); it++) {
- add_file_permission(*it, 'w');
- }
- writable_file_name_set.insert("/dev/null");
- if (config.allow_proc) {
- syscall_max_cnt[__NR_clone ] = -1;
- syscall_max_cnt[__NR_fork ] = -1;
- syscall_max_cnt[__NR_vfork ] = -1;
- syscall_max_cnt[__NR_nanosleep ] = -1;
- syscall_max_cnt[__NR_execve ] = -1;
- }
- if (config.type == "python2") {
- syscall_max_cnt[__NR_set_tid_address] = 1;
- syscall_max_cnt[__NR_set_robust_list] = 1;
- syscall_max_cnt[__NR_futex ] = -1;
- syscall_max_cnt[__NR_getdents ] = -1;
- syscall_max_cnt[__NR_getdents64 ] = -1;
- # ifdef UOJ_JUDGER_BASESYSTEM_UBUNTU1804
- syscall_max_cnt[__NR_prlimit64 ] = -1;
- syscall_max_cnt[__NR_getpid ] = -1;
- syscall_max_cnt[__NR_sysinfo ] = -1;
- # endif
- readable_file_name_set.insert("/usr/bin/python2.7");
- readable_file_name_set.insert("/usr/lib/python2.7/");
- readable_file_name_set.insert("/usr/bin/lib/python2.7/");
- readable_file_name_set.insert("/usr/local/lib/python2.7/");
- readable_file_name_set.insert("/usr/lib/pymodules/python2.7/");
- readable_file_name_set.insert("/usr/bin/Modules/");
- readable_file_name_set.insert("/usr/bin/pybuilddir.txt");
- # ifdef UOJ_JUDGER_BASESYSTEM_UBUNTU1804
- readable_file_name_set.insert("/usr/lib/locale/");
- readable_file_name_set.insert(config.work_path + "/answer.code");
- # endif
- statable_file_name_set.insert("/usr");
- statable_file_name_set.insert("/usr/bin");
- } else if (config.type == "python3") {
- syscall_max_cnt[__NR_set_tid_address] = 1;
- syscall_max_cnt[__NR_set_robust_list] = 1;
- syscall_max_cnt[__NR_futex ] = -1;
- syscall_max_cnt[__NR_getdents ] = -1;
- syscall_max_cnt[__NR_getdents64 ] = -1;
- # ifdef UOJ_JUDGER_BASESYSTEM_UBUNTU1804
- syscall_max_cnt[__NR_prlimit64 ] = -1;
- syscall_max_cnt[__NR_getrandom ] = -1;
- syscall_max_cnt[__NR_sysinfo ] = -1;
- syscall_max_cnt[__NR_getpid ] = -1;
- # endif
- readable_file_name_set.insert("/usr/bin/python3");
- readable_file_name_set.insert("/usr/lib/python3/");
- # ifdef UOJ_JUDGER_PYTHON3_VERSION
- readable_file_name_set.insert("/usr/bin/python" UOJ_JUDGER_PYTHON3_VERSION);
- readable_file_name_set.insert("/usr/lib/python" UOJ_JUDGER_PYTHON3_VERSION "/");
- readable_file_name_set.insert("/usr/bin/lib/python" UOJ_JUDGER_PYTHON3_VERSION "/");
- readable_file_name_set.insert("/usr/local/lib/python" UOJ_JUDGER_PYTHON3_VERSION "/");
- # else
- readable_file_name_set.insert("/usr/bin/python3.4");
- readable_file_name_set.insert("/usr/lib/python3.4/");
- readable_file_name_set.insert("/usr/bin/lib/python3.4/");
- readable_file_name_set.insert("/usr/local/lib/python3.4/");
- # endif
- readable_file_name_set.insert("/usr/bin/pyvenv.cfg");
- readable_file_name_set.insert("/usr/pyvenv.cfg");
- readable_file_name_set.insert("/usr/bin/Modules/");
- readable_file_name_set.insert("/usr/bin/pybuilddir.txt");
- readable_file_name_set.insert("/usr/lib/dist-python");
- # ifdef UOJ_JUDGER_BASESYSTEM_UBUNTU1804
- readable_file_name_set.insert("/usr/lib/locale/");
- readable_file_name_set.insert(config.work_path + "/answer.code");
- # endif
- statable_file_name_set.insert("/usr");
- statable_file_name_set.insert("/usr/bin");
- statable_file_name_set.insert("/usr/lib");
- # ifdef UOJ_JUDGER_BASESYSTEM_UBUNTU1804
- statable_file_name_set.insert("/usr/lib/python36.zip");
- # endif
- } else if (config.type == "java8") {
- syscall_max_cnt[__NR_gettid ] = -1;
- syscall_max_cnt[__NR_set_tid_address] = 1;
- syscall_max_cnt[__NR_set_robust_list] = 14;
- syscall_max_cnt[__NR_futex ] = -1;
- syscall_max_cnt[__NR_uname ] = 1;
- syscall_max_cnt[__NR_clone ] = 13;
- syscall_max_cnt[__NR_getdents ] = 4;
- syscall_max_cnt[__NR_clock_getres ] = 2;
- syscall_max_cnt[__NR_setrlimit ] = 1;
- syscall_max_cnt[__NR_sched_getaffinity] = -1;
- syscall_max_cnt[__NR_sched_yield ] = -1;
- # ifdef UOJ_JUDGER_BASESYSTEM_UBUNTU1804
- syscall_max_cnt[__NR_prlimit64 ] = -1;
- syscall_max_cnt[__NR_getpid ] = -1;
- syscall_max_cnt[__NR_sysinfo ] = -1;
- syscall_max_cnt[__NR_clone ] = -1;
- syscall_max_cnt[__NR_set_robust_list] = -1;
- syscall_max_cnt[__NR_prctl ] = -1;
- # endif
- syscall_should_soft_ban[__NR_socket ] = true;
- syscall_should_soft_ban[__NR_connect ] = true;
- syscall_should_soft_ban[__NR_geteuid ] = true;
- syscall_should_soft_ban[__NR_getuid ] = true;
- soft_ban_file_name_set.insert("/etc/nsswitch.conf");
- soft_ban_file_name_set.insert("/etc/passwd");
- add_file_permission("/usr/lib/jvm/java-8-openjdk-amd64/", 'r');
- readable_file_name_set.insert("/sys/devices/system/cpu/");
- readable_file_name_set.insert("/proc/");
- # ifdef UOJ_JUDGER_BASESYSTEM_UBUNTU1804
- readable_file_name_set.insert("/sys/fs/cgroup/cpu/");
- readable_file_name_set.insert("/sys/fs/cgroup/cpu,cpuacct/");
- readable_file_name_set.insert("/sys/fs/cgroup/memory/");
- readable_file_name_set.insert("/usr/lib/locale/");
- # endif
- statable_file_name_set.insert("/usr/java/");
- statable_file_name_set.insert("/tmp/");
- } else if (config.type == "java11") {
- syscall_max_cnt[__NR_gettid ] = -1;
- syscall_max_cnt[__NR_set_tid_address] = 1;
- syscall_max_cnt[__NR_set_robust_list] = 15;
- syscall_max_cnt[__NR_futex ] = -1;
- syscall_max_cnt[__NR_uname ] = 1;
- syscall_max_cnt[__NR_clone ] = 14;
- syscall_max_cnt[__NR_getdents ] = 4;
- syscall_max_cnt[__NR_clock_getres ] = 2;
- syscall_max_cnt[__NR_setrlimit ] = 1;
- syscall_max_cnt[__NR_sched_getaffinity] = -1;
- syscall_max_cnt[__NR_sched_yield ] = -1;
- # ifdef UOJ_JUDGER_BASESYSTEM_UBUNTU1804
- syscall_max_cnt[__NR_prlimit64 ] = -1;
- syscall_max_cnt[__NR_getpid ] = -1;
- syscall_max_cnt[__NR_sysinfo ] = -1;
- syscall_max_cnt[__NR_clone ] = -1;
- syscall_max_cnt[__NR_set_robust_list] = -1;
- syscall_max_cnt[__NR_uname ] = -1;
- syscall_max_cnt[__NR_clock_getres ] = -1;
- syscall_max_cnt[__NR_pread64 ] = -1;
- syscall_max_cnt[__NR_prctl ] = -1;
- syscall_max_cnt[__NR_nanosleep ] = -1;
- # endif
- syscall_should_soft_ban[__NR_socket ] = true;
- syscall_should_soft_ban[__NR_connect ] = true;
- syscall_should_soft_ban[__NR_geteuid ] = true;
- syscall_should_soft_ban[__NR_getuid ] = true;
- soft_ban_file_name_set.insert("/etc/nsswitch.conf");
- soft_ban_file_name_set.insert("/etc/passwd");
- add_file_permission("/usr/lib/jvm/java-11-openjdk-amd64/", 'r');
- readable_file_name_set.insert("/sys/devices/system/cpu/");
- readable_file_name_set.insert("/proc/");
- # ifdef UOJ_JUDGER_BASESYSTEM_UBUNTU1804
- readable_file_name_set.insert("/sys/fs/cgroup/cpu/");
- readable_file_name_set.insert("/sys/fs/cgroup/cpu,cpuacct/");
- readable_file_name_set.insert("/sys/fs/cgroup/memory/");
- readable_file_name_set.insert("/usr/share/java/");
- readable_file_name_set.insert("/usr/lib/locale/");
- readable_file_name_set.insert("/etc/oracle/java/usagetracker.properties");
- # endif
- statable_file_name_set.insert("/usr/java/");
- statable_file_name_set.insert("/tmp/");
- # ifdef UOJ_JUDGER_BASESYSTEM_UBUNTU1804
- statable_file_name_set.insert("/usr/share/");
- # endif
- } else if (config.type == "compiler") {
- // syscall_max_cnt[__NR_rseq ] = -1;
- // syscall_max_cnt[__NR_newfstatat ] = -1;
- // syscall_max_cnt[__NR_clone3 ] = -1;
- readable_file_name_set.insert("/etc/ld.so.conf");
- readable_file_name_set.insert("/etc/ld.so.conf.d/");
- syscall_max_cnt[__NR_gettid ] = -1;
- syscall_max_cnt[__NR_set_tid_address] = -1;
- syscall_max_cnt[__NR_set_robust_list] = -1;
- syscall_max_cnt[__NR_futex ] = -1;
- syscall_max_cnt[__NR_getpid ] = -1;
- syscall_max_cnt[__NR_vfork ] = -1;
- syscall_max_cnt[__NR_fork ] = -1;
- syscall_max_cnt[__NR_clone ] = -1;
- syscall_max_cnt[__NR_execve ] = -1;
- syscall_max_cnt[__NR_wait4 ] = -1;
- syscall_max_cnt[__NR_clock_gettime ] = -1;
- syscall_max_cnt[__NR_clock_getres ] = -1;
- syscall_max_cnt[__NR_setrlimit ] = -1;
- syscall_max_cnt[__NR_pipe ] = -1;
- syscall_max_cnt[__NR_getdents64 ] = -1;
- syscall_max_cnt[__NR_getdents ] = -1;
- syscall_max_cnt[__NR_umask ] = -1;
- syscall_max_cnt[__NR_rename ] = -1;
- syscall_max_cnt[__NR_chmod ] = -1;
- syscall_max_cnt[__NR_mkdir ] = -1;
- syscall_max_cnt[__NR_chdir ] = -1;
- syscall_max_cnt[__NR_fchdir ] = -1;
- syscall_max_cnt[__NR_ftruncate ] = -1; // for javac = =
- syscall_max_cnt[__NR_sched_getaffinity] = -1; // for javac = =
- syscall_max_cnt[__NR_sched_yield ] = -1; // for javac = =
- syscall_max_cnt[__NR_uname ] = -1; // for javac = =
- syscall_max_cnt[__NR_sysinfo ] = -1; // for javac = =
- # ifdef UOJ_JUDGER_BASESYSTEM_UBUNTU1804
- syscall_max_cnt[__NR_prlimit64 ] = -1;
- syscall_max_cnt[__NR_getrandom ] = -1;
- syscall_max_cnt[__NR_pread64 ] = -1;
- syscall_max_cnt[__NR_prctl ] = -1;
- syscall_max_cnt[__NR_nanosleep ] = -1;
- syscall_max_cnt[__NR_socketpair ] = -1;
- # endif
- syscall_should_soft_ban[__NR_socket ] = true; // for javac
- syscall_should_soft_ban[__NR_connect ] = true; // for javac
- syscall_should_soft_ban[__NR_geteuid ] = true; // for javac
- syscall_should_soft_ban[__NR_getuid ] = true; // for javac
- writable_file_name_set.insert("/tmp/");
- readable_file_name_set.insert(config.work_path);
- writable_file_name_set.insert(config.work_path + "/");
- readable_file_name_set.insert(abspath(0, string(self_path) + "/../runtime") + "/");
- # ifdef UOJ_JUDGER_BASESYSTEM_UBUNTU1804
- readable_file_name_set.insert("/sys/fs/cgroup/cpu/");
- readable_file_name_set.insert("/sys/fs/cgroup/cpu,cpuacct/");
- readable_file_name_set.insert("/sys/fs/cgroup/memory/");
- readable_file_name_set.insert("/etc/oracle/java/usagetracker.properties");
- # endif
- readable_file_name_set.insert("system_root");
- readable_file_name_set.insert("/usr/");
- readable_file_name_set.insert("/lib/");
- readable_file_name_set.insert("/lib64/");
- readable_file_name_set.insert("/bin/");
- readable_file_name_set.insert("/sbin/");
- // readable_file_name_set.insert("/proc/meminfo");
- // readable_file_name_set.insert("/proc/self/");
- readable_file_name_set.insert("/sys/devices/system/cpu/");
- readable_file_name_set.insert("/proc/");
- soft_ban_file_name_set.insert("/etc/nsswitch.conf"); // for javac = =
- soft_ban_file_name_set.insert("/etc/passwd"); // for javac = =
- readable_file_name_set.insert("/etc/timezone");
- # ifdef UOJ_JUDGER_FPC_VERSION
- readable_file_name_set.insert("/etc/fpc-" UOJ_JUDGER_FPC_VERSION ".cfg.d/");
- # else
- readable_file_name_set.insert("/etc/fpc-2.6.2.cfg.d/");
- # endif
- readable_file_name_set.insert("/etc/fpc.cfg");
- statable_file_name_set.insert("/*");
- }
- }
- string read_string_from_regs(reg_val_t addr, pid_t pid) {
- char res[MaxPathLen + 1], *ptr = res;
- while (ptr != res + MaxPathLen) {
- *(reg_val_t*)ptr = ptrace(PTRACE_PEEKDATA, pid, addr, NULL);
- for (int i = 0; i < sizeof(reg_val_t); i++, ptr++, addr++) {
- if (*ptr == 0) {
- return res;
- }
- }
- }
- res[MaxPathLen] = 0;
- return res;
- }
- string read_abspath_from_regs(reg_val_t addr, pid_t pid) {
- return abspath(pid, read_string_from_regs(addr, pid));
- }
- inline void soft_ban_syscall(pid_t pid, user_regs_struct reg) {
- reg.REG_SYSCALL += 1024;
- ptrace(PTRACE_SETREGS, pid, NULL, ®);
- }
- inline bool on_dgs_file_detect(pid_t pid, user_regs_struct reg, const string &fn) {
- if (is_soft_ban_file(fn)) {
- soft_ban_syscall(pid, reg);
- return true;
- } else {
- return false;
- }
- }
- inline bool check_safe_syscall(pid_t pid, bool need_show_trace_details) {
- struct user_regs_struct reg;
- ptrace(PTRACE_GETREGS, pid, NULL, ®);
- int cur_instruction = ptrace(PTRACE_PEEKTEXT, pid, reg.rip - 2, NULL) & 0xffff;
- if (cur_instruction != 0x050f) {
- if (need_show_trace_details) {
- fprintf(stderr, "informal syscall %d\n", cur_instruction);
- }
- return false;
- }
- int syscall = (int)reg.REG_SYSCALL;
- if (0 > syscall || syscall >= 1000) {
- return false;
- }
- if (need_show_trace_details) {
- fprintf(stderr, "syscall %d\n", (int)syscall);
- }
- if (syscall_should_soft_ban[syscall]) {
- soft_ban_syscall(pid, reg);
- } else if (syscall_max_cnt[syscall]-- == 0) {
- if (need_show_trace_details) {
- fprintf(stderr, "dgs %d\n", (int)syscall);
- }
- return false;
- }
- if (syscall == __NR_open || syscall == __NR_openat) {
- reg_val_t fn_addr;
- reg_val_t flags;
- if (syscall == __NR_open) {
- fn_addr = reg.REG_ARG0;
- flags = reg.REG_ARG1;
- } else {
- fn_addr = reg.REG_ARG1;
- flags = reg.REG_ARG2;
- }
- string fn = read_abspath_from_regs(fn_addr, pid);
- if (need_show_trace_details) {
- fprintf(stderr, "open ");
- switch (flags & O_ACCMODE) {
- case O_RDONLY:
- fprintf(stderr, "r ");
- break;
- case O_WRONLY:
- fprintf(stderr, "w ");
- break;
- case O_RDWR:
- fprintf(stderr, "rw");
- break;
- default:
- fprintf(stderr, "??");
- break;
- }
- fprintf(stderr, " %s\n", fn.c_str());
- }
- bool is_read_only = (flags & O_ACCMODE) == O_RDONLY &&
- (flags & O_CREAT) == 0 &&
- (flags & O_EXCL) == 0 &&
- (flags & O_TRUNC) == 0;
- if (is_read_only) {
- if (realpath(fn) != "" && !is_readable_file(fn)) {
- return on_dgs_file_detect(pid, reg, fn);
- }
- } else {
- if (!is_writable_file(fn)) {
- return on_dgs_file_detect(pid, reg, fn);
- }
- }
- } else if (syscall == __NR_readlink || syscall == __NR_readlinkat) {
- reg_val_t fn_addr;
- if (syscall == __NR_readlink) {
- fn_addr = reg.REG_ARG0;
- } else {
- fn_addr = reg.REG_ARG1;
- }
- string fn = read_abspath_from_regs(fn_addr, pid);
- if (need_show_trace_details) {
- fprintf(stderr, "readlink %s\n", fn.c_str());
- }
- if (!is_readable_file(fn)) {
- return on_dgs_file_detect(pid, reg, fn);
- }
- } else if (syscall == __NR_unlink || syscall == __NR_unlinkat) {
- reg_val_t fn_addr;
- if (syscall == __NR_unlink) {
- fn_addr = reg.REG_ARG0;
- } else {
- fn_addr = reg.REG_ARG1;
- }
- string fn = read_abspath_from_regs(fn_addr, pid);
- if (need_show_trace_details) {
- fprintf(stderr, "unlink %s\n", fn.c_str());
- }
- if (!is_writable_file(fn)) {
- return on_dgs_file_detect(pid, reg, fn);
- }
- } else if (syscall == __NR_access) {
- reg_val_t fn_addr = reg.REG_ARG0;
- string fn = read_abspath_from_regs(fn_addr, pid);
- if (need_show_trace_details) {
- fprintf(stderr, "access %s\n", fn.c_str());
- }
- if (!is_statable_file(fn)) {
- return on_dgs_file_detect(pid, reg, fn);
- }
- } else if (syscall == __NR_stat || syscall == __NR_lstat) {
- reg_val_t fn_addr = reg.REG_ARG0;
- string fn = read_abspath_from_regs(fn_addr, pid);
- if (need_show_trace_details) {
- fprintf(stderr, "stat %s\n", fn.c_str());
- }
- if (!is_statable_file(fn)) {
- return on_dgs_file_detect(pid, reg, fn);
- }
- } else if (syscall == __NR_execve) {
- reg_val_t fn_addr = reg.REG_ARG0;
- string fn = read_abspath_from_regs(fn_addr, pid);
- if (need_show_trace_details) {
- fprintf(stderr, "execve %s\n", fn.c_str());
- }
- if (!is_readable_file(fn)) {
- return on_dgs_file_detect(pid, reg, fn);
- }
- } else if (syscall == __NR_chmod || syscall == __NR_rename) {
- reg_val_t fn_addr = reg.REG_ARG0;
- string fn = read_abspath_from_regs(fn_addr, pid);
- if (need_show_trace_details) {
- fprintf(stderr, "change %s\n", fn.c_str());
- }
- if (!is_writable_file(fn)) {
- return on_dgs_file_detect(pid, reg, fn);
- }
- }
- return true;
- }
- inline void on_syscall_exit(pid_t pid, bool need_show_trace_details) {
- struct user_regs_struct reg;
- ptrace(PTRACE_GETREGS, pid, NULL, ®);
- if (need_show_trace_details) {
- if ((long long int)reg.REG_SYSCALL >= 1024) {
- fprintf(stderr, "ban sys %lld\n", (long long int)reg.REG_SYSCALL - 1024);
- } else {
- fprintf(stderr, "exitsys %lld (ret %d)\n", (long long int)reg.REG_SYSCALL, (int)reg.REG_RET);
- }
- }
- if ((long long int)reg.REG_SYSCALL >= 1024) {
- reg.REG_SYSCALL -= 1024;
- reg.REG_RET = -EACCES;
- ptrace(PTRACE_SETREGS, pid, NULL, ®);
- }
- }
|