From 56688ed6d0b18f68ac8ddd82c4944c5d2777d20a Mon Sep 17 00:00:00 2001 From: pzread Date: Fri, 1 Mar 2013 22:30:00 +0800 Subject: Taiwan Online Judge Alpha 1 --- toj/center/pro/packpro.sh | 3 + toj/center/src/Makefile | 25 + toj/center/src/center.h | 53 + toj/center/src/center_com.h | 70 + toj/center/src/center_judge.cpp | 524 +++++++ toj/center/src/center_judge.h | 106 ++ toj/center/src/center_manage.cpp | 308 ++++ toj/center/src/center_manage.h | 23 + toj/center/src/center_server.cpp | 192 +++ toj/center/src/center_server.h | 45 + toj/center/src/jmod_test.h | 15 + toj/center/src/jmod_test_check.cpp | 104 ++ toj/center/src/jmod_test_check.h | 4 + toj/center/src/jmod_test_line.cpp | 189 +++ toj/center/src/jmod_test_line.h | 11 + toj/center/src/jmod_test_manage.cpp | 98 ++ toj/center/src/jmod_test_manage.h | 35 + toj/center/src/judge_def.h | 20 + toj/center/src/judge_server.cpp | 697 +++++++++ toj/center/src/judge_server.h | 107 ++ toj/center/src/judgk.h | 16 + toj/center/src/judgk_com.h | 25 + toj/center/src/judgk_hyperio.c | 417 ++++++ toj/center/src/judgk_hyperio.h | 53 + toj/center/src/judgk_mod.c | 75 + toj/center/src/judgk_mod.h | 31 + toj/center/src/judgk_proc.c | 251 ++++ toj/center/src/judgk_proc.h | 18 + toj/center/src/judgk_security.c | 2698 +++++++++++++++++++++++++++++++++++ toj/center/src/judgk_security.h | 197 +++ toj/center/src/judgk_syscall.c | 240 ++++ toj/center/src/judgk_syscall.h | 70 + toj/center/src/judgk_syscall_asm.S | 54 + toj/center/src/judgm_lib.h | 369 +++++ toj/center/src/judgm_line.h | 19 + toj/center/src/judgm_manage.h | 27 + toj/center/src/netio.h | 192 +++ toj/center/src/pack.cpp | 175 +++ toj/center/src/pack.h | 20 + toj/center/src/tpool.h | 169 +++ 40 files changed, 7745 insertions(+) create mode 100755 toj/center/pro/packpro.sh create mode 100644 toj/center/src/Makefile create mode 100644 toj/center/src/center.h create mode 100644 toj/center/src/center_com.h create mode 100644 toj/center/src/center_judge.cpp create mode 100644 toj/center/src/center_judge.h create mode 100644 toj/center/src/center_manage.cpp create mode 100644 toj/center/src/center_manage.h create mode 100644 toj/center/src/center_server.cpp create mode 100644 toj/center/src/center_server.h create mode 100644 toj/center/src/jmod_test.h create mode 100644 toj/center/src/jmod_test_check.cpp create mode 100644 toj/center/src/jmod_test_check.h create mode 100644 toj/center/src/jmod_test_line.cpp create mode 100644 toj/center/src/jmod_test_line.h create mode 100644 toj/center/src/jmod_test_manage.cpp create mode 100644 toj/center/src/jmod_test_manage.h create mode 100755 toj/center/src/judge_def.h create mode 100644 toj/center/src/judge_server.cpp create mode 100644 toj/center/src/judge_server.h create mode 100755 toj/center/src/judgk.h create mode 100644 toj/center/src/judgk_com.h create mode 100644 toj/center/src/judgk_hyperio.c create mode 100644 toj/center/src/judgk_hyperio.h create mode 100755 toj/center/src/judgk_mod.c create mode 100755 toj/center/src/judgk_mod.h create mode 100755 toj/center/src/judgk_proc.c create mode 100755 toj/center/src/judgk_proc.h create mode 100755 toj/center/src/judgk_security.c create mode 100755 toj/center/src/judgk_security.h create mode 100755 toj/center/src/judgk_syscall.c create mode 100755 toj/center/src/judgk_syscall.h create mode 100755 toj/center/src/judgk_syscall_asm.S create mode 100644 toj/center/src/judgm_lib.h create mode 100755 toj/center/src/judgm_line.h create mode 100644 toj/center/src/judgm_manage.h create mode 100644 toj/center/src/netio.h create mode 100644 toj/center/src/pack.cpp create mode 100644 toj/center/src/pack.h create mode 100644 toj/center/src/tpool.h (limited to 'toj/center') diff --git a/toj/center/pro/packpro.sh b/toj/center/pro/packpro.sh new file mode 100755 index 0000000..b53a707 --- /dev/null +++ b/toj/center/pro/packpro.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +tar -jcvf ../tmp/propack/$1.tar.bz2 -C $1 . diff --git a/toj/center/src/Makefile b/toj/center/src/Makefile new file mode 100644 index 0000000..dcfab80 --- /dev/null +++ b/toj/center/src/Makefile @@ -0,0 +1,25 @@ +ifneq ($(KERNELRELEASE),) + judgk-objs := judgk_mod.o judgk_proc.o judgk_syscall.o judgk_syscall_asm.o judgk_security.o judgk_hyperio.o + obj-m := judgk.o +else + KERNEL_SOURCE := /usr/lib/modules/$(shell uname -r)/build + PWD := $(shell pwd) +default: + ${MAKE} -C ${KERNEL_SOURCE} M=${PWD} modules + mv judgk.ko ../judge/ + + g++ -rdynamic -fvisibility=hidden -O2 center_server.cpp center_manage.cpp center_judge.cpp pack.cpp /srv/http/toj/php/event_exec.cpp -ldl -lpq -ltar -lbz2 -ljson -lcurl -pthread -o center_server + g++ -O2 judge_server.cpp pack.cpp -ldl -lbz2 -ltar -pthread -o judge_server + mv center_server ../ + mv judge_server ../judge/ + + g++ -shared -fPIC -fvisibility=hidden -O2 jmod_test_manage.cpp -ldl -ljson -pthread -o jmod_test_manage.so + g++ -shared -fPIC -fvisibility=hidden -O2 jmod_test_line.cpp -ljson -pthread -o jmod_test_line.so + g++ -shared -fPIC -fvisibility=hidden -O2 jmod_test_check.cpp -o jmod_test_check.so + mv jmod_test_manage.so ../jmod/jmod_test/ + mv jmod_test_line.so ../jmod/jmod_test/ + mv jmod_test_check.so ../jmod/jmod_test/ + tar -jcvf ../tmp/jmodpack/jmod_test.tar.bz2 -C ../jmod/jmod_test . +clean: + ${MAKE} -C ${KERNEL_SOURCE} SUBDIRS=${PWD} clean +endif diff --git a/toj/center/src/center.h b/toj/center/src/center.h new file mode 100644 index 0000000..a143df0 --- /dev/null +++ b/toj/center/src/center.h @@ -0,0 +1,53 @@ +class center_jmod_info{ +public: + char name[NAME_MAX + 1]; + int cacheid; + void *manage_dll; + void *manage_sub_fn; + void *manage_res_fn; + + center_jmod_info(char *name,int cacheid){ + this->name[0] = '\0'; + strncat(this->name,name,sizeof(this->name)); + this->cacheid = cacheid; + this->manage_dll = NULL; + this->manage_sub_fn = NULL; + this->manage_res_fn = NULL; + } +}; + +class center_pro_info{ +public: + int proid; + int cacheid; + center_jmod_info *jmod_info; + int lang_flag; + + center_pro_info(int proid,int cacheid,center_jmod_info *jmod_info,int lang_flag){ + this->proid = proid; + this->cacheid = cacheid; + this->jmod_info = jmod_info; + this->lang_flag = lang_flag; + } +}; + +class center_submit_info{ +public: + int subid; + int uid; + center_jmod_info *jmod_info; + center_pro_info *pro_info; + int lang; + char *param; + void *jmod_manage_data; + + center_submit_info(int subid,int uid,center_jmod_info *jmod_info,center_pro_info *pro_info,int lang,char *param){ + this->subid = subid; + this->uid = uid; + this->jmod_info = jmod_info; + this->pro_info = pro_info; + this->lang = lang; + this->param = param; + this->jmod_manage_data = NULL; + } +}; diff --git a/toj/center/src/center_com.h b/toj/center/src/center_com.h new file mode 100644 index 0000000..73f3ff3 --- /dev/null +++ b/toj/center/src/center_com.h @@ -0,0 +1,70 @@ +#define CENTER_COMCODE_SETID 1 +#define CENTER_COMCODE_SETINFO 2 +#define CENTER_COMCODE_SUBMIT 3 +#define CENTER_COMCODE_RESULT 4 + +#define CENTER_COMCODE_SETPRO 10 +#define CENTER_COMCODE_REQPRO 11 +#define CENTER_COMCODE_SENDPRO 12 +#define CENTER_COMCODE_SETJMOD 13 +#define CENTER_COMCODE_REQJMOD 14 +#define CENTER_COMCODE_SENDJMOD 15 + +#define CENTER_COMCODE_REQCODE 20 +#define CENTER_COMCODE_SENDCODE 21 + +struct center_com_header{ + int code; + int size; +}__attribute__((packed)); +struct center_com_setid{ + int id; //0:new judge +}__attribute__((packed)); +struct center_com_setinfo{ + int avail; +}__attribute__((packed)); +struct center_com_submit{ + int subid; + int proid; + int lang; + char set_data[JUDGE_SET_DATAMAX]; +}__attribute__((packed)); +struct center_com_result{ //just result header + int subid; +}__attribute__((packed)); + +struct center_com_setpro{ + int proid; + int cacheid; + int type; //0:add problem 1:drop problem +}__attribute__((packed)); +struct center_com_reqpro{ + int proid; +}__attribute__((packed)); +struct center_com_sendpro{ + int proid; + int cacheid; + size_t filesize; +}__attribute__((packed)); + +struct center_com_setjmod{ + char jmod_name[NAME_MAX + 1]; + int cacheid; + int type; //0:add jmod 1:drop jmod +}__attribute__((packed)); +struct center_com_reqjmod{ + char jmod_name[NAME_MAX + 1]; +}__attribute__((packed)); +struct center_com_sendjmod{ + char jmod_name[NAME_MAX + 1]; + int cacheid; + size_t filesize; +}__attribute__((packed)); + +struct center_com_reqcode{ + int subid; +}__attribute__((packed)); +struct center_com_sendcode{ + int subid; + size_t filesize; +}__attribute__((packed)); diff --git a/toj/center/src/center_judge.cpp b/toj/center/src/center_judge.cpp new file mode 100644 index 0000000..38837cc --- /dev/null +++ b/toj/center/src/center_judge.cpp @@ -0,0 +1,524 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include"netio.h" +#include"judge_def.h" +#include"center.h" +#include"center_com.h" +#include"center_judge.h" + +int judge_info::last_id = 0; +judge_info::judge_info(){ + last_id++; + this->id = last_id; + this->avail = 0; + + judge_idmap.insert(std::pair(id,this)); + judge_runlist.push_back(this); + judge_it = judge_runlist.end(); + judge_it--; +} +judge_info::~judge_info(){ + judge_idmap.erase(id); + judge_runlist.erase(judge_it); +} +int judge_info::setavail(int avail){ + int old; + + old = this->avail; + this->avail = avail; + if(this->avail > 0 && old <= 0){ + judge_runlist.erase(judge_it); + judge_runlist.push_front(this); + judge_it = judge_runlist.begin(); + }else if(this->avail <= 0 && old > 0){ + judge_runlist.erase(judge_it); + judge_runlist.push_back(this); + judge_it = judge_runlist.end(); + judge_it--; + } + + return 0; +} +int judge_info::setinfo(int avail){ + setavail(avail); + return 0; +} +int judge_info::submit(judge_submit_info *sub_info){ + setavail(avail - 1); + conn_main->send_submit(sub_info); + return 0; +} +int judge_info::result(int subid,char *res_data){ + setavail(avail + 1); + + printf("submitid:%d\n",subid); + center_manage_result(subid,res_data); + + judge_submit_waitqueue(); + return 0; +} + + +judge_conn::judge_conn(int fd):netio(fd){ + this->info = NULL; + this->recv_dispatch_fn = new netio_iofn(this,&judge_conn::recv_dispatch); + this->recv_setid_fn = new netio_iofn(this,&judge_conn::recv_setid); + this->recv_setinfo_fn = new netio_iofn(this,&judge_conn::recv_setinfo); + this->recv_result_fn = new netio_iofn(this,&judge_conn::recv_result); + this->recv_setpro_fn = new netio_iofn(this,&judge_conn::recv_setpro); + this->recv_reqpro_fn = new netio_iofn(this,&judge_conn::recv_reqpro); + this->recv_setjmod_fn = new netio_iofn(this,&judge_conn::recv_setjmod); + this->recv_reqjmod_fn = new netio_iofn(this,&judge_conn::recv_reqjmod); + this->recv_reqcode_fn = new netio_iofn(this,&judge_conn::recv_reqcode); +} +judge_conn::~judge_conn(){ + info->conn_list.erase(conn_it); + if(info->conn_main == this){ + info->conn_main = NULL; + } + if(info->conn_list.empty()){ + delete info; + } + + delete recv_dispatch_fn; + delete recv_setid_fn; + delete recv_setinfo_fn; + delete recv_result_fn; + delete recv_setpro_fn; + delete recv_reqpro_fn; + delete recv_setjmod_fn; + delete recv_reqjmod_fn; + delete recv_reqcode_fn; +} +char* judge_conn::create_combuf(int code,int size,int &len,void **data){ + char *buf; + center_com_header *header; + + buf = new char[sizeof(center_com_header) + size]; + header = (center_com_header*)buf; + header->code = code; + header->size = size; + len = sizeof(center_com_header) + size; + *data = (void*)(buf + sizeof(center_com_header)); + + return buf; +} +int judge_conn::send_setid(int judgeid){ + char *write_buf; + int write_len; + center_com_setid *setid; + + write_buf = create_combuf(CENTER_COMCODE_SETID,sizeof(center_com_setid),write_len,(void**)&setid); + setid->id = judgeid; + writebytes(write_buf,write_len,NULL,NULL); + + return 0; +} +int judge_conn::send_submit(judge_submit_info *sub_info){ + char *write_buf; + int write_len; + center_com_submit *sub; + + printf(" send submit %d\n",sub_info->subid); + + write_buf = create_combuf(CENTER_COMCODE_SUBMIT,sizeof(center_com_submit),write_len,(void**)&sub); + sub->subid = sub_info->subid; + sub->proid = sub_info->proid; + sub->lang = sub_info->lang; + memcpy(sub->set_data,sub_info->set_data,sub_info->set_len); + writebytes(write_buf,write_len,NULL,NULL); + + delete sub_info; + return 0; +} +int judge_conn::send_setpro(int *proid,int *cacheid,int type,int count){ + int i; + + char *write_buf; + int write_len; + center_com_setpro *setpro; + + write_buf = create_combuf(CENTER_COMCODE_SETPRO,sizeof(center_com_setpro) * count,write_len,(void**)&setpro); + for(i = 0;i < count;i++){ + setpro[i].proid = proid[i]; + setpro[i].cacheid = cacheid[i]; + setpro[i].type = type; + } + writebytes(write_buf,write_len,NULL,NULL); + + return 0; +} +int judge_conn::send_setjmod(char **jmod_name,int *cacheid,int type,int count){ + int i; + + char *write_buf; + int write_len; + center_com_setjmod *setjmod; + + write_buf = create_combuf(CENTER_COMCODE_SETJMOD,sizeof(center_com_setjmod) * count,write_len,(void**)&setjmod); + for(i = 0;i < count;i++){ + setjmod[i].jmod_name[0] = '\0'; + strncat(setjmod[i].jmod_name,jmod_name[i],sizeof(setjmod[i].jmod_name)); + setjmod[i].cacheid = cacheid[i]; + setjmod[i].type = type; + } + writebytes(write_buf,write_len,NULL,NULL); + + return 0; +} +int judge_conn::readidle(){ + readbytes(new center_com_header,sizeof(center_com_header),recv_dispatch_fn,NULL); + return 0; +} +void judge_conn::recv_dispatch(void *buf,size_t len,void *data){ + center_com_header *header; + char *readbuf; + + header = (center_com_header*)buf; + readbuf = new char[header->size]; + + printf("code:%d size:%d\n",header->code,header->size); + switch(header->code){ + case CENTER_COMCODE_SETID: + readbytes(readbuf,header->size,recv_setid_fn,NULL); + break; + case CENTER_COMCODE_SETINFO: + readbytes(readbuf,header->size,recv_setinfo_fn,NULL); + break; + case CENTER_COMCODE_RESULT: + readbytes(readbuf,header->size,recv_result_fn,NULL); + break; + case CENTER_COMCODE_SETPRO: + readbytes(readbuf,header->size,recv_setpro_fn,NULL); + break; + case CENTER_COMCODE_REQPRO: + readbytes(readbuf,header->size,recv_reqpro_fn,NULL); + break; + case CENTER_COMCODE_SETJMOD: + readbytes(readbuf,header->size,recv_setjmod_fn,NULL); + break; + case CENTER_COMCODE_REQJMOD: + readbytes(readbuf,header->size,recv_reqjmod_fn,NULL); + break; + case CENTER_COMCODE_REQCODE: + readbytes(readbuf,header->size,recv_reqcode_fn,NULL); + break; + } + + delete header; +} +void judge_conn::recv_setid(void *buf,size_t len,void *data){ + center_com_setid *setid; + std::map::iterator it; + + setid = (center_com_setid*)buf; + if(setid->id == 0){ + info = new judge_info(); + + info->conn_list.push_front(this); + conn_it = info->conn_list.begin(); + info->conn_main = this; + + this->send_setid(info->id); + }else{ + if((it = judge_idmap.find(setid->id)) != judge_idmap.end()){ + info = it->second; + info->conn_list.push_front(this); + conn_it = info->conn_list.begin(); + } + } + + delete setid; +} +void judge_conn::recv_setinfo(void *buf,size_t len,void *data){ + int i; + int count; + + center_com_setinfo *setinfo; + char **jmod_name; + std::map::iterator jmod_it; + int *proid; + int *cacheid; + std::map::iterator pro_it; + + setinfo = (center_com_setinfo*)buf; + info->setinfo(setinfo->avail); + + count = center_manage_jmodmap.size(); + jmod_name = new char*[count]; + cacheid = new int[count]; + jmod_it = center_manage_jmodmap.begin(); + for(i = 0;i < count;i++,jmod_it++){ + jmod_name[i] = jmod_it->second->name; + cacheid[i] = jmod_it->second->cacheid; + } + send_setjmod(jmod_name,cacheid,0,count); + + delete jmod_name; + delete cacheid; + + count = center_manage_promap.size(); + proid = new int[count]; + cacheid = new int[count]; + pro_it = center_manage_promap.begin(); + for(i = 0;i < count;i++,pro_it++){ + proid[i] = pro_it->second->proid; + cacheid[i] = pro_it->second->cacheid; + } + send_setpro(proid,cacheid,0,count); + + delete proid; + delete cacheid; + + delete setinfo; +} +void judge_conn::recv_result(void *buf,size_t len,void *data){ + int subid; + char *res_data; + + subid = ((center_com_result*)buf)->subid; + res_data = (char*)((char*)buf + sizeof(center_com_result)); + + info->result(subid,res_data); + + delete (char*)buf; +} +void judge_conn::recv_setpro(void *buf,size_t len,void *data){ + int i; + int count; + + center_com_setpro *setpro; + std::map::iterator pro_it; + + count = len / sizeof(center_com_setpro); + setpro = (center_com_setpro*)buf; + for(i = 0;i < count;i++){ + if(setpro[i].type == 0){ + if((pro_it = center_manage_promap.find(setpro[i].proid)) == center_manage_promap.end()){ + continue; + } + if(pro_it->second->cacheid != setpro[i].cacheid){ + continue; + } + + info->pro_map.insert(std::pair(pro_it->second->proid,pro_it->second)); + }else if(setpro[i].type == 1){ + info->pro_map.erase(setpro[i].proid); + } + } + + judge_submit_waitqueue(); + delete setpro; +} +void judge_conn::recv_reqpro(void *buf,size_t len,void *data){ + center_com_reqpro *reqpro; + std::map::iterator pro_it; + center_pro_info *pro_info; + + char tpath[PATH_MAX + 1]; + int fd; + struct stat st; + + char *write_buf; + int write_len; + center_com_sendpro *sendpro; + + reqpro = (center_com_reqpro*)buf; + if((pro_it = center_manage_promap.find(reqpro->proid)) == center_manage_promap.end()){ + //fix + }else{ + pro_info = pro_it->second; + + snprintf(tpath,sizeof(tpath),"tmp/propack/%d.tar.bz2",pro_info->proid); + fd = open(tpath,O_RDONLY); + if(fstat(fd,&st)){ + //fix + }else{ + write_buf = create_combuf(CENTER_COMCODE_SENDPRO,sizeof(center_com_sendpro),write_len,(void**)&sendpro); + sendpro->proid = pro_info->proid; + sendpro->cacheid = pro_info->cacheid; + sendpro->filesize = st.st_size; + printf("sendpro:%lu\n",sendpro->filesize); + + writebytes(write_buf,write_len,NULL,NULL); + writefile(fd,st.st_size,NULL,NULL); + } + } + + delete reqpro; +} +void judge_conn::recv_setjmod(void *buf,size_t len,void *data){ + int i; + int count; + + center_com_setjmod *setjmod; + std::map::iterator jmod_it; + + count = len / sizeof(center_com_setjmod); + setjmod = (center_com_setjmod*)buf; + for(i = 0;i < count;i++){ + if(setjmod[i].type == 0){ + if((jmod_it = center_manage_jmodmap.find(setjmod[i].jmod_name)) == center_manage_jmodmap.end()){ + continue; + } + if(jmod_it->second->cacheid != setjmod[i].cacheid){ + continue; + } + + info->jmod_map.insert(std::pair(jmod_it->second->name,jmod_it->second)); + }else if(setjmod[i].type == 1){ + info->jmod_map.erase(setjmod[i].jmod_name); + } + } + + judge_submit_waitqueue(); + delete setjmod; +} +void judge_conn::recv_reqjmod(void *buf,size_t len,void *data){ + center_com_reqjmod *reqjmod; + std::map::iterator jmod_it; + center_jmod_info *jmod_info; + + char tpath[PATH_MAX + 1]; + int fd; + struct stat st; + + char *write_buf; + int write_len; + center_com_sendjmod *sendjmod; + + reqjmod = (center_com_reqjmod*)buf; + if((jmod_it = center_manage_jmodmap.find(reqjmod->jmod_name)) == center_manage_jmodmap.end()){ + //fix + }else{ + jmod_info = jmod_it->second; + + snprintf(tpath,sizeof(tpath),"tmp/jmodpack/%s.tar.bz2",jmod_info->name); + fd = open(tpath,O_RDONLY); + if(fstat(fd,&st)){ + //fix + }else{ + write_buf = create_combuf(CENTER_COMCODE_SENDJMOD,sizeof(center_com_sendjmod),write_len,(void**)&sendjmod); + sendjmod->jmod_name[0] = '\0'; + strncat(sendjmod->jmod_name,jmod_info->name,sizeof(sendjmod->jmod_name)); + sendjmod->cacheid = jmod_info->cacheid; + sendjmod->filesize = st.st_size; + printf("sendjmod:%lu\n",sendjmod->filesize); + + writebytes(write_buf,write_len,NULL,NULL); + writefile(fd,st.st_size,NULL,NULL); + } + } + + delete reqjmod; +} +void judge_conn::recv_reqcode(void *buf,size_t len,void *data){ + center_com_reqcode *reqcode; + char tpath[PATH_MAX + 1]; + int fd; + struct stat st; + + char *write_buf; + int write_len; + center_com_header *header; + center_com_sendcode *sendcode; + + reqcode = (center_com_reqcode*)buf; + snprintf(tpath,sizeof(tpath),"tmp/codepack/%d.tar.bz2",reqcode->subid); + fd = open(tpath,O_RDONLY); + if(fstat(fd,&st)){ + //fix + }else{ + write_buf = create_combuf(CENTER_COMCODE_SENDCODE,sizeof(center_com_sendcode),write_len,(void**)&sendcode); + sendcode->subid = reqcode->subid; + sendcode->filesize = st.st_size; + printf("sendcode:%lu\n",sendcode->filesize); + + writebytes(write_buf,write_len,NULL,NULL); + writefile(fd,st.st_size,NULL,NULL); + } + + delete reqcode; +} + + +static int judge_submit_waitqueue(){ + int count; + judge_submit_info *sub_info; + bool wait_flag; + std::list::iterator judge_it; + judge_info *info; + std::map::iterator pro_it; + center_pro_info *pro_info; + + count = judge_submitqueue.size(); + for(;count > 0;count--){ + sub_info = judge_submitqueue.front(); + judge_submitqueue.pop(); + + if((pro_it = center_manage_promap.find(sub_info->proid)) == center_manage_promap.end()){ + continue; + } + pro_info = pro_it->second; + + wait_flag = true; + for(judge_it = judge_runlist.begin();judge_it != judge_runlist.end();judge_it++){ + info = *judge_it; + if(info->avail <= 0){ + break; + } + if(info->pro_map.find(pro_info->proid) != info->pro_map.end() && info->jmod_map.find(pro_info->jmod_info->name) != info->jmod_map.end()){ + info->submit(sub_info); + wait_flag = false; + break; + } + } + if(wait_flag == true){ + judge_submitqueue.push(sub_info); + } + } + return 0; +} +int center_judge_init(){ + return 0; +} +void* center_judge_addconn(int fd){ + return new judge_conn(fd); +} +int center_judge_dispatch(int evflag,void *data){ + judge_conn *cinfo; + + cinfo = (judge_conn*)data; + if(evflag & EPOLLRDHUP){ + printf("close %d\n",cinfo->fd); + delete cinfo; + }else{ + if(evflag & EPOLLIN){ + cinfo->readio(); + } + if(evflag & EPOLLOUT){ + cinfo->writeio(); + } + } + + return 0; +} +int center_judge_submit(int subid,int proid,int lang,char *set_data,size_t set_len){ + judge_submitqueue.push(new judge_submit_info(subid,proid,lang,set_data,set_len)); + judge_submit_waitqueue(); + return 0; +} diff --git a/toj/center/src/center_judge.h b/toj/center/src/center_judge.h new file mode 100644 index 0000000..74b2daf --- /dev/null +++ b/toj/center/src/center_judge.h @@ -0,0 +1,106 @@ +class judge_info; +class judge_conn; +class judge_submit_info; + +class judge_info{ +private: + static int last_id; + +public: + int id; + int avail; + judge_conn *conn_main; + std::list conn_list; + std::list::iterator judge_it; + std::map pro_map; + std::map jmod_map; + + judge_info(); + ~judge_info(); + int setavail(int value); + int setinfo(int avail); + int submit(judge_submit_info *submit_info); + int result(int subid,char *res_data); +}; + +class judge_conn : public netio{ +private: + netio_iofn *recv_dispatch_fn; + netio_iofn *recv_setid_fn; + netio_iofn *recv_setinfo_fn; + netio_iofn *recv_result_fn; + netio_iofn *recv_setpro_fn; + netio_iofn *recv_reqpro_fn; + netio_iofn *recv_setjmod_fn; + netio_iofn *recv_reqjmod_fn; + netio_iofn *recv_reqcode_fn; + + char* create_combuf(int code,int size,int &len,void **data); + void recv_dispatch(void *buf,size_t len,void *data); + void recv_setid(void *buf,size_t len,void *data); + void recv_setinfo(void *buf,size_t len,void *data); + void recv_result(void *buf,size_t len,void *data); + void recv_setpro(void *buf,size_t len,void *data); + void recv_reqpro(void *buf,size_t len,void *data); + void recv_setjmod(void *buf,size_t len,void *data); + void recv_reqjmod(void *buf,size_t len,void *data); + void recv_reqcode(void *buf,size_t len,void *data); + +public: + judge_info *info; + std::list::iterator conn_it; + + judge_conn(int fd); + ~judge_conn(); + int send_setid(int judgeid); + int send_submit(judge_submit_info* submit_info); + int send_setpro(int *proid,int *cacheid,int type,int count); + int send_setjmod(char **jmod_name,int *cacheid,int type,int count); + virtual int readidle(); +}; + +class judge_submit_info{ +public: + int subid; + int proid; + int lang; + char set_data[JUDGE_SET_DATAMAX]; + size_t set_len; + + judge_submit_info(int subid,int proid,int lang,char *setdata,size_t setlen){ + this->subid = subid; + this->proid = proid; + this->lang = lang; + if(setlen > JUDGE_SET_DATAMAX){ + memcpy(this->set_data,setdata,JUDGE_SET_DATAMAX); + }else{ + memcpy(this->set_data,setdata,setlen); + } + this->set_len = setlen; + } +}; + +static int judge_submit_waitqueue(); + +static std::map judge_idmap; +static std::list judge_runlist; +static std::queue judge_submitqueue; + +int center_judge_init(); +void* center_judge_addconn(int fd); +int center_judge_dispatch(int evflag,void *data); +int center_judge_submit(int subid,int proid,int lang,char *setdata,size_t setlen); + +extern int center_manage_result(int subid,char *res_data); + +extern std::map center_manage_jmodmap; +extern std::map center_manage_promap; + + + +/*#define JUDGE_DB_MAXSCOREMAX 1024 +static int tmp_init(); +static int tmp_update(int submitid,int count,void *data); +static int server_updatedb(PGconn *sqlc,int submitid,int result_count,struct judgx_line_result *result); + +static PGconn *tmp_sqlc;*/ diff --git a/toj/center/src/center_manage.cpp b/toj/center/src/center_manage.cpp new file mode 100644 index 0000000..887bdff --- /dev/null +++ b/toj/center/src/center_manage.cpp @@ -0,0 +1,308 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include"tpool.h" +#include"/srv/http/toj/php/event_exec.h" +#include"center.h" +#include"judge_def.h" +#include"judgm_manage.h" +#include"center_manage.h" + +int center_manage_init(tpool **tpinfo){ + manage_packtp = new tpool(4); + manage_packtp->start(); + *tpinfo = manage_packtp; + + manage_packcode_thfn = new tpool_static_fn(manage_packcode_th); + manage_packcode_cbfn = new tpool_static_fn(manage_packcode_cb); + + center_manage_updatedata(); + return 0; +} +PGconn* center_manage_conndb(){ + return PQconnectdb("host=localhost port=5432 dbname=xxxxx user=xxxxx password=xxxxx"); +} +int center_manage_closedb(PGconn *conn){ + PQfinish(conn); + return 0; +} +int center_manage_updatedata(){ + int i; + + PGconn *db_conn; + PGresult *db_res; + int db_count; + center_jmod_info *jmod_info; + int proid; + int lang_flag; + std::map::iterator jmod_it; + center_pro_info *pro_info; + + if((db_conn = center_manage_conndb()) == NULL){ + return -1; + } + + db_res = PQexec(db_conn,"SELECT DISTINCT \"jmodname\" FROM \"mod\";"); + if(PQresultStatus(db_res) != PGRES_TUPLES_OK){ + center_manage_closedb(db_conn); + return -1; + } + + db_count = PQntuples(db_res); + for(i = 0;i < db_count;i++){ + jmod_info = new center_jmod_info(PQgetvalue(db_res,i,0),2); + center_manage_jmodmap.insert(std::pair(jmod_info->name,jmod_info)); + } + + PQclear(db_res); + + db_res = PQexec(db_conn,"SELECT \"proid\",\"jmodname\",\"lang\" FROM \"problem\" INNER JOIN \"mod\" ON (\"problem\".\"modid\"=\"mod\".\"modid\");"); + if(PQresultStatus(db_res) != PGRES_TUPLES_OK){ + center_manage_closedb(db_conn); + return -1; + } + + db_count = PQntuples(db_res); + for(i = 0;i < db_count;i++){ + sscanf(PQgetvalue(db_res,i,0),"%d",&proid); + sscanf(PQgetvalue(db_res,i,2),"%d",&lang_flag); + if((jmod_it = center_manage_jmodmap.find(PQgetvalue(db_res,i,1))) == center_manage_jmodmap.end()){ + continue; + } + pro_info = new center_pro_info(proid,1,jmod_it->second,lang_flag); + center_manage_promap.insert(std::pair(pro_info->proid,pro_info)); + } + + PQclear(db_res); + center_manage_closedb(db_conn); + return 0; +} +int center_manage_submit(int subid,char *param){ + PGconn *db_conn; + PGresult *db_res; + char *db_param[1]; + char db_subid[64]; + + int uid; + int proid; + int lang; + std::map::iterator pro_it; + center_pro_info *pro_info; + center_jmod_info *jmod_info; + center_submit_info *sub_info; + + if((db_conn = center_manage_conndb()) == NULL){ + return -1; + } + + snprintf(db_subid,sizeof(db_subid),"%d",subid); + db_param[0] = db_subid; + db_res = PQexecParams(db_conn, + "SELECT \"uid\",\"proid\",\"lang\" FROM \"submit\" WHERE \"subid\"=$1;", + 1, + NULL, + db_param, + NULL, + NULL, + 0); + if(PQresultStatus(db_res) != PGRES_TUPLES_OK){ + center_manage_closedb(db_conn); + return -1; + } + + sscanf(PQgetvalue(db_res,0,0),"%d",&uid); + sscanf(PQgetvalue(db_res,0,1),"%d",&proid); + sscanf(PQgetvalue(db_res,0,2),"%d",&lang); + PQclear(db_res); + center_manage_closedb(db_conn); + + if((pro_it = center_manage_promap.find(proid)) == center_manage_promap.end()){ + return -1; + } + pro_info = pro_it->second; + + if((lang & pro_info->lang_flag) == 0){ + return -1; + } + jmod_info = pro_info->jmod_info; + + sub_info = new center_submit_info(subid,uid,jmod_info,pro_info,lang,param); + center_manage_submap.insert(std::pair(sub_info->subid,sub_info)); + manage_packtp->add(manage_packcode_thfn,sub_info,manage_packcode_cbfn,sub_info); + + return 0; +} +static void manage_packcode_th(void *data){ + center_submit_info *sub_info; + int subid; + char dir_path[PATH_MAX + 1]; + char pack_path[PATH_MAX + 1]; + + sub_info = (center_submit_info*)data; + subid = sub_info->subid; + + snprintf(dir_path,sizeof(dir_path),"submit/%d/%d/data",(subid / 1000) * 1000,subid); + snprintf(pack_path,sizeof(pack_path),"tmp/codepack/%d.tar.bz2",subid); + pack_pack(pack_path,dir_path); +} +static void manage_packcode_cb(void *data){ + center_submit_info *sub_info; + center_jmod_info *jmod_info; + center_pro_info *pro_info; + + char cwd_path[PATH_MAX + 1]; + char tpath[PATH_MAX + 1]; + judgm_manage_submit_fn mod_sub_fn; + judgm_manage_submitinfo mod_sub_info; + FILE *set_file; + char lchr; + char tchr; + + sub_info = (center_submit_info*)data; + jmod_info = sub_info->jmod_info; + pro_info = sub_info->pro_info; + + if(jmod_info->manage_dll == NULL){ + getcwd(cwd_path,sizeof(cwd_path)); + snprintf(tpath,sizeof(tpath),"%s/jmod/%s/%s_manage.so",cwd_path,jmod_info->name,jmod_info->name); + + jmod_info->manage_dll = dlopen(tpath,RTLD_NOW); + jmod_info->manage_sub_fn = dlsym(jmod_info->manage_dll,"submit"); + jmod_info->manage_res_fn = dlsym(jmod_info->manage_dll,"result"); + } + mod_sub_fn = (judgm_manage_submit_fn)jmod_info->manage_sub_fn; + + mod_sub_info.uid = sub_info->uid; + mod_sub_info.subid = sub_info->subid; + mod_sub_info.proid = pro_info->proid; + mod_sub_info.lang = sub_info->lang; + mod_sub_info.param = sub_info->param; + snprintf(mod_sub_info.pro_path,sizeof(mod_sub_info.pro_path),"pro/%d",pro_info->proid); + + snprintf(tpath,sizeof(tpath),"pro/%d/setting",pro_info->proid); + set_file = fopen(tpath,"r"); + lchr = '\n'; + while((tchr = fgetc(set_file)) != EOF){ + if(lchr == '\n' && tchr == '='){ + while(fgetc(set_file) != '\n'); + break; + } + lchr = tchr; + } + mod_sub_info.set_file = set_file; + + mod_sub_fn(&mod_sub_info,&sub_info->jmod_manage_data); + + fclose(set_file); +} +static int manage_notice(int subid,int uid,int proid,int result,int runtime,int memory){ + char msg[4096]; + json_object *jso_msg; + json_object *jso_arg; + + jso_msg = json_object_new_object(); + json_object_object_add(jso_msg,"type",json_object_new_string("result")); + json_object_object_add(jso_msg,"subid",json_object_new_int(subid)); + json_object_object_add(jso_msg,"proid",json_object_new_int(proid)); + json_object_object_add(jso_msg,"result",json_object_new_int(result)); + json_object_object_add(jso_msg,"runtime",json_object_new_int(runtime)); + json_object_object_add(jso_msg,"memory",json_object_new_int(memory / 1024UL)); + + jso_arg = json_object_new_array(); + json_object_array_add(jso_arg,json_object_new_int(uid)); + json_object_array_add(jso_arg,jso_msg); + + printf("%d %d %d\n",uid,proid,event_exec("pzreadtest.php","center_result_event",json_object_get_string(jso_arg))); + json_object_put(jso_arg); + + return 0; +} + +int center_manage_result(int subid,char *res_data){ + int ret; + + std::map::iterator sub_it; + center_submit_info *sub_info; + center_jmod_info *jmod_info; + + char res_path[PATH_MAX + 1]; + judgm_manage_resultinfo res_info; + judgm_manage_result_fn res_fn; + + PGconn *db_conn; + PGresult *db_res; + char db_result[32]; + char db_score[32]; + char db_runtime[32]; + char db_memory[32]; + char db_subid[32]; + char *db_param[5]; + + if((sub_it = center_manage_submap.find(subid)) == center_manage_submap.end()){ + return -1; + } + sub_info = sub_it->second; + jmod_info = sub_info->jmod_info; + + res_info.uid = sub_info->uid; + res_info.subid = subid; + res_info.proid = sub_info->pro_info->proid; + snprintf(res_path,sizeof(res_path),"submit/%d/%d/result",(subid / 1000) * 1000,subid); + res_info.res_path = res_path; + res_info.res_data = res_data; + res_fn = (judgm_manage_result_fn)jmod_info->manage_res_fn; + ret = res_fn(&res_info,sub_info->jmod_manage_data); + if(ret == 1){ + center_manage_submap.erase(sub_it); + + if((db_conn = center_manage_conndb()) == NULL){ + return -1; + } + + snprintf(db_result,sizeof(db_result),"%d",res_info.result); + snprintf(db_score,sizeof(db_score),"%d",(int)res_info.score); + snprintf(db_runtime,sizeof(db_runtime),"%lu",res_info.runtime); + snprintf(db_memory,sizeof(db_memory),"%lu",res_info.memory / 1024UL); + snprintf(db_subid,sizeof(db_subid),"%d",subid); + db_param[0] = db_result; + db_param[1] = db_score; + db_param[2] = db_runtime; + db_param[3] = db_memory; + db_param[4] = db_subid; + db_res = PQexecParams(db_conn, + "UPDATE \"submit\" SET \"result\"=$1,\"score\"=$2,\"runtime\"=$3,\"memory\"=$4 WHERE \"subid\"=$5;", + 5, + NULL, + db_param, + NULL, + NULL, + 0); + PQclear(db_res); + center_manage_closedb(db_conn); + + manage_notice(subid,sub_info->uid,sub_info->pro_info->proid,res_info.result,res_info.runtime,res_info.memory); + + delete sub_info; + }else{ + return -1; + } + + return 0; +} +DLL_PUBLIC int center_manage_queuesubmit(int subid,int proid,int lang,char *set_data,size_t set_len){ + center_judge_submit(subid,proid,lang,set_data,set_len); + return 0; +} diff --git a/toj/center/src/center_manage.h b/toj/center/src/center_manage.h new file mode 100644 index 0000000..27e1bc9 --- /dev/null +++ b/toj/center/src/center_manage.h @@ -0,0 +1,23 @@ +static void manage_packcode_th(void *data); +static void manage_packcode_cb(void *data); +static int manage_notice(int subid,int uid,int proid,int result,int runtime,int memory); + +static tpool *manage_packtp; +static tpool_static_fn *manage_packcode_thfn; +static tpool_static_fn *manage_packcode_cbfn; + +int center_manage_init(tpool **tpinfo); +PGconn* center_manage_conndb(); +int center_manage_closedb(PGconn *conn); +int center_manage_updatedata(); +int center_manage_submit(int subid,char *param); +int center_manage_result(int subid,char *res_data); +DLL_PUBLIC int center_manage_queuesubmit(int subid,int proid,int lang,char *set_data,size_t set_len); + +std::map center_manage_jmodmap; +std::map center_manage_promap; +std::map center_manage_submap; + +extern int pack_pack(char *pack_path,char *dir_path); +extern int pack_unpack(char *pack_path,char *dir_path); +extern int center_judge_submit(int subid,int proid,int lang,char *set_data,size_t set_len); diff --git a/toj/center/src/center_server.cpp b/toj/center/src/center_server.cpp new file mode 100644 index 0000000..406e0fc --- /dev/null +++ b/toj/center/src/center_server.cpp @@ -0,0 +1,192 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include"tpool.h" +#include"center_server.h" + +server_epevdata::server_epevdata(int fd,int type,void *data){ + this->fd = fd; + this->type = type; + this->data = data; +} + + +server_web_conn::server_web_conn(int fd){ + this->fd = fd; + this->off = 0; + this->count = 0; +} +server_web_conn::~server_web_conn(){ + epoll_ctl(server_epfd,EPOLL_CTL_DEL,fd,NULL); + close(fd); +} +int server_web_conn::readio(){ + int ret; + char c; + int len; + int subid; + char *param; + + while((ret = read(fd,&c,1)) > 0){ + buf[off] = c; + off++; + if(c == '\0'){ + count++; + if(count == 2){ + break; + } + } + } + + if(count == 2){ + off = 0; + count = 0; + + sscanf(buf,"%d",&subid); + param = buf + strlen(buf) + 1; + printf("%d %s\n",subid,param); + + center_manage_submit(subid,param); + + write(fd,"S",2); + } + + return 0; +} + + +static int server_addepev(int fd,unsigned int flag,int type,void *data){ + server_epevdata *epevdata; + epoll_event epev; + + epevdata = new server_epevdata(fd,type,data); + epev.events = flag; + epev.data.ptr = epevdata; + epoll_ctl(server_epfd,EPOLL_CTL_ADD,fd,&epev); + + return 0; +} +static int server_delepev(server_epevdata *epevdata){ + epoll_ctl(server_epfd,EPOLL_CTL_DEL,epevdata->fd,NULL); + delete epevdata; + return 0; +} +int main(){ + int ret; + int i; + + int judge_sfd; + int web_sfd; + int cfd; + sockaddr_in saddr; + sockaddr_in caddr; + epoll_event epev; + epoll_event epevs[SERVER_EPOLL_MAXEVENT]; + int nevs; + + unsigned int ev_flag; + server_epevdata *epevdata; + server_web_conn *winfo; + tpool *tpinfo; + + signal(SIGPIPE,SIG_IGN); + server_epfd = epoll_create1(0); + center_manage_init(&tpinfo); + server_addepev(tpinfo->fd,EPOLLIN | EPOLLET,SERVER_EPEV_TPOOL,tpinfo); + center_judge_init(); + + + judge_sfd = socket(AF_INET,SOCK_STREAM | SOCK_NONBLOCK,6); + saddr.sin_family = AF_INET; + saddr.sin_port = htons(SERVER_JUDGE_PORT); + //saddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + //saddr.sin_addr.s_addr = htonl(INADDR_ANY); + saddr.sin_addr.s_addr = inet_addr("10.8.0.2"); + setsockopt(judge_sfd,SOL_SOCKET,SO_REUSEADDR,&saddr,sizeof(saddr)); + bind(judge_sfd,(sockaddr*)&saddr,sizeof(saddr)); + + server_addepev(judge_sfd,EPOLLIN | EPOLLET,SERVER_EPEV_JUDGESERVER,NULL); + listen(judge_sfd,4096); + + web_sfd = socket(AF_INET,SOCK_STREAM | SOCK_NONBLOCK,6); + saddr.sin_family = AF_INET; + saddr.sin_port = htons(SERVER_WEB_PORT); + saddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + //saddr.sin_addr.s_addr = htonl(INADDR_ANY); + setsockopt(web_sfd,SOL_SOCKET,SO_REUSEADDR,&saddr,sizeof(saddr)); + bind(web_sfd,(sockaddr*)&saddr,sizeof(saddr)); + + server_addepev(web_sfd,EPOLLIN | EPOLLET,SERVER_EPEV_WEBSERVER,NULL); + listen(web_sfd,4096); + + while(true){ + nevs = epoll_wait(server_epfd,epevs,SERVER_EPOLL_MAXEVENT,-1); + for(i = 0;i < nevs;i++){ + ev_flag = epevs[i].events; + epevdata = (server_epevdata*)epevs[i].data.ptr; + + if(epevdata->type == SERVER_EPEV_JUDGESERVER){ + while(true){ + ret = 0; + if((cfd = accept4(epevdata->fd,(sockaddr*)&caddr,(socklen_t*)&ret,SOCK_NONBLOCK)) == -1){ + break; + } + + server_addepev(cfd,EPOLLIN | EPOLLOUT | EPOLLRDHUP | EPOLLET,SERVER_EPEV_JUDGECLIENT,center_judge_addconn(cfd)); + } + }else if(epevdata->type == SERVER_EPEV_JUDGECLIENT){ + center_judge_dispatch(ev_flag,epevdata->data); + if(ev_flag & EPOLLRDHUP){ + server_delepev(epevdata); + } + }else if(epevdata->type == SERVER_EPEV_WEBSERVER){ + printf("test\n"); + while(true){ + ret = 0; + if((cfd = accept4(epevdata->fd,(sockaddr*)&caddr,(socklen_t*)&ret,SOCK_NONBLOCK)) == -1){ + break; + } + + server_addepev(cfd,EPOLLIN | EPOLLOUT | EPOLLRDHUP | EPOLLET,SERVER_EPEV_WEBCLIENT,new server_web_conn(cfd)); + } + }else if(epevdata->type == SERVER_EPEV_WEBCLIENT){ + winfo = (server_web_conn*)epevdata->data; + if(ev_flag & EPOLLIN){ + winfo->readio(); + } + if(ev_flag & EPOLLRDHUP){ + delete winfo; + delete (server_epevdata*)epev.data.ptr; + } + }else if(epevdata->type == SERVER_EPEV_TPOOL){ + tpinfo = (tpool*)epevdata->data; + if(ev_flag & EPOLLIN){ + tpinfo->done(); + } + } + } + } + + close(judge_sfd); + close(server_epfd); + close(web_sfd); + + return 0; +} diff --git a/toj/center/src/center_server.h b/toj/center/src/center_server.h new file mode 100644 index 0000000..140a1d4 --- /dev/null +++ b/toj/center/src/center_server.h @@ -0,0 +1,45 @@ +#define SERVER_JUDGE_PORT 2573 +#define SERVER_WEB_PORT 2501 +#define SERVER_EPOLL_MAXEVENT 4096 + +#define SERVER_EPEV_JUDGESERVER 0 +#define SERVER_EPEV_JUDGECLIENT 1 +#define SERVER_EPEV_WEBSERVER 2 +#define SERVER_EPEV_WEBCLIENT 3 +#define SERVER_EPEV_TPOOL 4 +class server_epevdata{ +public: + int fd; + int type; + void *data; + + server_epevdata(int fd,int type,void *data); +}; + +class server_web_conn{ +private: + int fd; + char buf[65536]; + int off; + int count; + +public: + server_web_conn(int fd); + ~server_web_conn(); + int readio(); +}; + +static int server_addepev(int fd,unsigned int flag,int type,void *data); +static int server_delepev(server_epevdata *epevdata); +static int server_epfd; + +extern int center_manage_init(tpool **tpinfo); +extern int center_manage_submit(int subid,char *param); + +extern int center_judge_init(); +extern void* center_judge_addconn(int fd); +extern int center_judge_dispatch(int ev_flag,void *data); +extern int center_judge_submit(int subid,int proid); + +extern int pack_pack(char *pack_path,char *dir_path); +extern int pack_unpack(char *pack_path,char *target_path); diff --git a/toj/center/src/jmod_test.h b/toj/center/src/jmod_test.h new file mode 100644 index 0000000..49381fc --- /dev/null +++ b/toj/center/src/jmod_test.h @@ -0,0 +1,15 @@ +typedef int (*check_init_fn)(int judgk_modfd,char *datapath,char *runpath); +typedef int (*check_run_fn)(int &status); +typedef int (*check_stop_fn)(); + +struct line_set_data{ + int test_id; +}; +struct line_result_data{ + int test_id; + int status; + double score; + unsigned long runtime; + unsigned long memory; + char errmsg[4096]; +}; diff --git a/toj/center/src/jmod_test_check.cpp b/toj/center/src/jmod_test_check.cpp new file mode 100644 index 0000000..df7368f --- /dev/null +++ b/toj/center/src/jmod_test_check.cpp @@ -0,0 +1,104 @@ +#include +#include +#include +#include +#include +#include +#include + +#include"judge_def.h" +#include"judgm_lib.h" +#include"jmod_test.h" +#include"jmod_test_check.h" + +static int ansfd; +static judgm_hyperio *hyperio; +static int tty_idx; + +int p[2]; + +DLL_PUBLIC int init(int judgk_modfd,char *datapath,char *runpath){ + char tpath[PATH_MAX + 1]; + char dstpath[PATH_MAX + 1]; + + pipe(p); + + snprintf(tpath,sizeof(tpath),"%s/in",datapath); + snprintf(dstpath,sizeof(dstpath),"%s/in",runpath); + if(link(tpath,dstpath)){ + return -1; + } + snprintf(tpath,sizeof(tpath),"%s/ans",datapath); + if((ansfd = open(tpath,O_RDONLY)) == -1){ + return -1; + } + + //hyperio = new judgm_hyperio(judgk_modfd); + //tty_idx = hyperio->tty_idx; + + return 0; +} +DLL_PUBLIC int run(int &status){ + int ret; + + char *inbuf; + char *ansbuf; + + status = JUDGE_AC; + inbuf = new char[65536]; + ansbuf = new char[65536]; + + /*while((ret = read(ansfd,ansbuf,65536)) > 0){ + if(hyperio->compare(ansbuf,ret)){ + status = JUDGE_WA; + break; + } + } + if(status == JUDGE_AC && hyperio->wait() > 0){ + status = JUDGE_WA; + } + + delete inbuf; + delete ansbuf; + close(ansfd); + delete hyperio;*/ + + close(p[1]); + while((ret = read(p[0],inbuf,65536)) > 0){ + if(read(ansfd,ansbuf,ret) != ret){ + status = JUDGE_WA; + break; + } + if(memcmp(ansbuf,inbuf,ret)){ + status = JUDGE_WA; + break; + } + } + if(status == JUDGE_AC && read(ansfd,ansbuf,1) > 0){ + status = JUDGE_WA; + } + + return 0; +} +DLL_PUBLIC int proc(){ + int infd; + int outfd; + + if((infd = open("in",O_RDONLY)) == -1){ + return -1; + } + /*if((outfd = judgm_hyperio::get_ttyfd(tty_idx)) == -1){ + return -1; + }*/ + + close(p[0]); + outfd = p[1]; + dup2(infd,0); + dup2(outfd,1); + dup2(outfd,2); + + return 0; +} +DLL_PUBLIC int stop(){ + return 0; +} diff --git a/toj/center/src/jmod_test_check.h b/toj/center/src/jmod_test_check.h new file mode 100644 index 0000000..57bc2c6 --- /dev/null +++ b/toj/center/src/jmod_test_check.h @@ -0,0 +1,4 @@ +DLL_PUBLIC int init(int judgk_modfd,char *datapath,char *runpath); +DLL_PUBLIC int run(int &status); +DLL_PUBLIC int proc(); +DLL_PUBLIC int stop(); diff --git a/toj/center/src/jmod_test_line.cpp b/toj/center/src/jmod_test_line.cpp new file mode 100644 index 0000000..85340ad --- /dev/null +++ b/toj/center/src/jmod_test_line.cpp @@ -0,0 +1,189 @@ +#include +#include +#include +#include +#include +#include + +#include"judge_def.h" +#include"judgm_lib.h" +#include"judgm_line.h" +#include"jmod_test.h" +#include"jmod_test_line.h" + +static int line_load_setfile(FILE *set_file,int test_id,int &timelimit,int &memlimit,double &score){ + int ret; + + json_object *jso; + char buf[JUDGE_SET_FILEMAX]; + + fread(buf,1,sizeof(buf),set_file); + jso = json_tokener_parse(buf); + + timelimit = json_object_get_int(json_object_object_get(jso,"timelimit")); + memlimit = json_object_get_int(json_object_object_get(jso,"memlimit")); + score = json_object_get_double(json_object_array_get_idx(json_object_object_get(jso,"score"),test_id - 1)); + + json_object_put(jso); + return 0; +} +static void line_sigaction(int sig_num,siginfo_t *sig_info,void *context){ + if(sig_info->si_pid == line_proc->pid && line_proc->status == JUDGE_RUN){ + if(!line_proc->proc_wait(false)){ + line_chk_stop_fn(); + } + } +} +static int line_sig_set(){ + struct sigaction sig; + + sig.sa_sigaction = line_sigaction; + sigemptyset(&sig.sa_mask); + sig.sa_flags = SA_SIGINFO | SA_RESTART; + if(sigaction(SIGCHLD,&sig,NULL)){ + return -1; + } + + return 0; +} +static int line_sig_restore(){ + struct sigaction sig; + + sig.sa_handler = SIG_DFL; + sigemptyset(&sig.sa_mask); + sig.sa_flags = 0; + if(sigaction(SIGCHLD,&sig,NULL)){ + return -1; + } + + return 0; +} +static int line_sig_block(){ + sigset_t mask; + + sigemptyset(&mask); + sigaddset(&mask,SIGCHLD); + if(pthread_sigmask(SIG_BLOCK,&mask,NULL)){ + return -1; + } + + return 0; +} +static int line_sig_unblock(){ + sigset_t mask; + + sigemptyset(&mask); + sigaddset(&mask,SIGCHLD); + if(pthread_sigmask(SIG_UNBLOCK,&mask,NULL)){ + return -1; + } + + return 0; +} +static int line_sig_wait(){ + sigset_t mask; + int num; + + sigfillset(&mask); + sigdelset(&mask,SIGKILL); + sigdelset(&mask,SIGTERM); + sigdelset(&mask,SIGINT); + sigdelset(&mask,SIGCHLD); + sigsuspend(&mask); + + return 0; +} +DLL_PUBLIC int run(judgm_line_info *info){ + int i; + + line_result_data *res_data; + + int set_timelimit; + int set_memlimit; + double set_score; + line_set_data *set_data; + + char main_path[PATH_MAX + 1]; + char exe_path[PATH_MAX + 1]; + + check_init_fn chk_init_fn; + check_run_fn chk_run_fn; + judgm_proc_check_fn chk_proc_fn; + + char data_path[PATH_MAX + 1]; + int chk_status; + + set_data = (line_set_data*)info->set_data; + + res_data = (line_result_data*)info->res_data; + info->res_len = sizeof(line_result_data); + + res_data->test_id = set_data->test_id; + res_data->status = JUDGE_ERR; + res_data->score = 0; + res_data->runtime = 0; + res_data->memory = 0; + + if(line_load_setfile(info->set_file,set_data->test_id,set_timelimit,set_memlimit,set_score)){ + return -1; + } + + snprintf(main_path,sizeof(main_path),"%s/main.cpp",info->code_path); + snprintf(exe_path,sizeof(exe_path),"%s/test",info->run_path); + if(judgm_compile(info->subid,main_path,exe_path,info->lang,false,res_data->errmsg,sizeof(res_data->errmsg))){ + res_data->status = JUDGE_CE; + return -1; + } + + chk_init_fn = (check_init_fn)dlsym(info->check_dll,"init"); + chk_run_fn = (check_run_fn)dlsym(info->check_dll,"run"); + chk_proc_fn = (judgm_proc_check_fn)dlsym(info->check_dll,"proc"); + line_chk_stop_fn = (check_stop_fn)dlsym(info->check_dll,"stop"); + line_proc = new judgm_proc(info->judgk_modfd,info->run_path,exe_path,set_timelimit,(set_timelimit * 10 + 5000),set_memlimit,chk_proc_fn); + + snprintf(data_path,sizeof(data_path),"%s/private/%d",info->pro_path,set_data->test_id); + if(chk_init_fn(info->judgk_modfd,data_path,info->run_path)){ + delete line_proc; + return -1; + } + if(line_sig_set()){ + delete line_proc; + return -1; + } + + if(line_proc->proc_run()){ + delete line_proc; + return -1; + } + chk_run_fn(chk_status); + + line_sig_block(); + if(line_proc->status == JUDGE_RUN){ + line_proc->proc_kill(); + line_sig_wait(); + } + line_sig_unblock(); + + printf("check status %d proc status %d\n",chk_status,line_proc->status); + + if(line_sig_restore()){ + delete line_proc; + return -1; + } + + if(line_proc->status != JUDGE_AC){ + res_data->status = line_proc->status; + }else{ + res_data->status = chk_status; + } + if(res_data->status == JUDGE_AC){ + res_data->score = set_score; + }else{ + res_data->score = 0; + } + res_data->runtime = line_proc->runtime; + res_data->memory = line_proc->memory; + + delete line_proc; + return 0; +} diff --git a/toj/center/src/jmod_test_line.h b/toj/center/src/jmod_test_line.h new file mode 100644 index 0000000..c09a503 --- /dev/null +++ b/toj/center/src/jmod_test_line.h @@ -0,0 +1,11 @@ +static int line_load_setfile(FILE *set_file,int test_id,int &timelimit,int &memlimit,double &score); +static int line_sig_set(); +static int line_sig_restore(); +static int line_sig_block(); +static int line_sig_unblock(); +static int line_sig_wait(); + +static judgm_proc *line_proc; +static check_stop_fn line_chk_stop_fn; + +DLL_PUBLIC int run(judgm_line_info *info); diff --git a/toj/center/src/jmod_test_manage.cpp b/toj/center/src/jmod_test_manage.cpp new file mode 100644 index 0000000..e4738df --- /dev/null +++ b/toj/center/src/jmod_test_manage.cpp @@ -0,0 +1,98 @@ +#include +#include +#include +#include +#include +#include + +#include"judge_def.h" +#include"judgm_lib.h" +#include"judgm_manage.h" +#include"jmod_test.h" +#include"jmod_test_manage.h" + +static void __attribute__ ((constructor)) manage_init(){ + manage_queuesubmit_fn = (judgm_manage_queuesubmit_fn)dlsym(dlopen(NULL,RTLD_NOW),"center_manage_queuesubmit"); +} +static int manage_load_setfile(FILE *set_file,int &count){ + int ret; + + json_object *jso; + char buf[JUDGE_SET_FILEMAX]; + + fread(buf,1,sizeof(buf),set_file); + jso = json_tokener_parse(buf); + + count = json_object_get_int(json_object_object_get(jso,"count")); + + json_object_put(jso); + return 0; +} + +DLL_PUBLIC int submit(judgm_manage_submitinfo *info,void **manage_data){ + int i; + + int count; + manage_result_info *res_info; + line_set_data set_data; + + manage_load_setfile(info->set_file,count); + + res_info = new manage_result_info(count); + *manage_data = res_info; + + for(i = 0;i < count;i++){ + set_data.test_id = i + 1; + manage_queuesubmit_fn(info->subid,info->proid,info->lang,(char*)&set_data,sizeof(line_set_data)); + } + + return 0; +} +DLL_PUBLIC int result(judgm_manage_resultinfo *info,void *manage_data){ + manage_result_info *res_info; + line_result_data *res_data; + json_object *jso_item; + char tpath[PATH_MAX + 1]; + + res_info = (manage_result_info*)manage_data; + res_info->test_count++; + + res_data = (line_result_data*)info->res_data; + if(res_data->status > res_info->test_result){ + res_info->test_result = res_data->status; + } + res_info->test_totalscore += res_data->score; + res_info->test_totalruntime += res_data->runtime; + if(res_data->memory > res_info->test_maxmemory){ + res_info->test_maxmemory = res_data->memory; + } + + jso_item = json_object_new_object(); + json_object_object_add(jso_item,"status",json_object_new_int(res_data->status)); + json_object_object_add(jso_item,"score",json_object_new_double(res_data->score)); + json_object_object_add(jso_item,"runtime",json_object_new_int64(res_data->runtime)); + json_object_object_add(jso_item,"memory",json_object_new_int64(res_data->memory / 1024UL)); + if(res_data->status == JUDGE_CE){ + json_object_object_add(jso_item,"errmsg",json_object_new_string(res_data->errmsg)); + } + json_object_array_put_idx(res_info->jso_resarray,res_data->test_id - 1,jso_item); + + printf("jmod count %d %d\n",res_info->test_count,res_info->test_allcount); + if(res_info->test_count == res_info->test_allcount){ + snprintf(tpath,sizeof(tpath),"%s/result",info->res_path); + json_object_to_file_ext(tpath,res_info->jso_res,JSON_C_TO_STRING_PLAIN); + + info->result = res_info->test_result; + info->score = res_info->test_totalscore; + info->runtime = res_info->test_totalruntime; + info->memory = res_info->test_maxmemory; + + printf("finish result\n"); + + delete res_info; + return 1; + } + return 0; +} + + diff --git a/toj/center/src/jmod_test_manage.h b/toj/center/src/jmod_test_manage.h new file mode 100644 index 0000000..811274a --- /dev/null +++ b/toj/center/src/jmod_test_manage.h @@ -0,0 +1,35 @@ +class manage_result_info{ +public: + int test_allcount; + int test_count; + int test_result; + double test_totalscore; + unsigned long test_totalruntime; + unsigned long test_maxmemory; + json_object *jso_res; + json_object *jso_resarray; + + manage_result_info(int allcount){ + this->test_allcount = allcount; + this->test_count = 0; + this->test_result = JUDGE_AC; + this->test_totalscore = 0; + this->test_totalruntime = 0; + this->test_maxmemory = 0; + + this->jso_res = json_object_new_object(); + this->jso_resarray = json_object_new_array(); + json_object_object_add(this->jso_res,"result",this->jso_resarray); + } + ~manage_result_info(){ + json_object_put(jso_res); + } +}; + +DLL_PUBLIC int submit(judgm_manage_submitinfo *info,void **manage_data); +DLL_PUBLIC int result(judgm_manage_resultinfo *info,void *manage_data); + +static void __attribute__ ((constructor)) manage_init(); +static int manage_load_setfile(FILE *setfile,int &count); + +static judgm_manage_queuesubmit_fn manage_queuesubmit_fn; diff --git a/toj/center/src/judge_def.h b/toj/center/src/judge_def.h new file mode 100755 index 0000000..fad8c4d --- /dev/null +++ b/toj/center/src/judge_def.h @@ -0,0 +1,20 @@ +#define JUDGE_AC 0 +#define JUDGE_WA 1 +#define JUDGE_TLE 2 +#define JUDGE_MLE 3 +#define JUDGE_RF 4 +#define JUDGE_RE 5 +#define JUDGE_CE 6 +#define JUDGE_ERR 7 +#define JUDGE_WAIT 100 +#define JUDGE_RUN 101 + +#define JUDGE_CPP 0x1 +#define JUDGE_JAVA 0x2 +#define JUDGE_PASCEL 0x4 + +#define JUDGE_SET_FILEMAX 65536 +#define JUDGE_SET_DATAMAX 4096 +#define JUDGE_RES_DATAMAX 65536 + +#define DLL_PUBLIC extern "C" __attribute__ ((visibility ("default"))) diff --git a/toj/center/src/judge_server.cpp b/toj/center/src/judge_server.cpp new file mode 100644 index 0000000..2741459 --- /dev/null +++ b/toj/center/src/judge_server.cpp @@ -0,0 +1,697 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include"judge_def.h" +#include"netio.h" +#include"tpool.h" +#include"center_com.h" +#include"judgm_line.h" +#include"judgm_lib.h" +#include"judge_server.h" + +server_epevdata::server_epevdata(int fd,int type,void *data){ + this->fd = fd; + this->type = type; + this->data = data; +} + + +server_conn::server_conn(int fd):netio(fd){ + this->recv_dispatch_fn = new netio_iofn(this,&server_conn::recv_dispatch); + this->recv_setid_fn = new netio_iofn(this,&server_conn::recv_setid); + this->recv_submit_fn = new netio_iofn(this,&server_conn::recv_submit); + this->recv_setpro_fn = new netio_iofn(this,&server_conn::recv_setpro); + this->recv_sendpro_fn = new netio_iofn(this,&server_conn::recv_sendpro); + this->done_sendpro_fn = new netio_iofn(this,&server_conn::done_sendpro); + this->recv_setjmod_fn = new netio_iofn(this,&server_conn::recv_setjmod); + this->recv_sendjmod_fn = new netio_iofn(this,&server_conn::recv_sendjmod); + this->done_sendjmod_fn = new netio_iofn(this,&server_conn::done_sendjmod); + this->recv_sendcode_fn = new netio_iofn(this,&server_conn::recv_sendcode); + this->done_sendcode_fn = new netio_iofn(this,&server_conn::done_sendcode); + this->tp_unpackpro_thfn = new tpool_fn(this,&server_conn::tp_unpackpro_th); + this->tp_unpackpro_cbfn = new tpool_fn(this,&server_conn::tp_unpackpro_cb); + this->tp_unpackjmod_thfn = new tpool_fn(this,&server_conn::tp_unpackjmod_th); + this->tp_unpackjmod_cbfn = new tpool_fn(this,&server_conn::tp_unpackjmod_cb); + this->tp_unpackcode_thfn = new tpool_fn(this,&server_conn::tp_unpackcode_th); + this->tp_unpackcode_cbfn = new tpool_fn(this,&server_conn::tp_unpackcode_cb); + this->tp_judge_thfn = new tpool_fn(this,&server_conn::tp_judge_th); + this->tp_judge_cbfn = new tpool_fn(this,&server_conn::tp_judge_cb); + + send_setid(); +} +char* server_conn::create_combuf(int code,int size,int &len,void **data){ + char *buf; + center_com_header *header; + + buf = new char[sizeof(center_com_header) + size]; + header = (center_com_header*)buf; + header->code = code; + header->size = size; + len = sizeof(center_com_header) + size; + *data = (void*)(buf + sizeof(center_com_header)); + + return buf; +} +int server_conn::send_setid(){ + char *write_buf; + int write_len; + center_com_setid *setid; + + write_buf = create_combuf(CENTER_COMCODE_SETID,sizeof(center_com_setid),write_len,(void**)&setid); + setid->id = server_id; + writebytes(write_buf,write_len,NULL,NULL); + + return 0; +} +int server_conn::send_setinfo(){ + char *write_buf; + int write_len; + center_com_setinfo *setinfo; + + write_buf = create_combuf(CENTER_COMCODE_SETINFO,sizeof(center_com_setinfo),write_len,(void**)&setinfo); + setinfo->avail = server_avail; + writebytes(write_buf,write_len,NULL,NULL); + + return 0; +} +int server_conn::send_result(int subid,char *res_data,size_t res_len){ + char *write_buf; + int write_len; + center_com_result *result; + + if(res_len > JUDGE_RES_DATAMAX){ + return -1; + } + + write_buf = create_combuf(CENTER_COMCODE_RESULT,sizeof(center_com_result) + res_len,write_len,(void**)&result); + result->subid = subid; + memcpy((void*)(write_buf + sizeof(center_com_header) + sizeof(center_com_result)),res_data,res_len); + writebytes(write_buf,write_len,NULL,NULL); + + return 0; +} +int server_conn::send_setpro(int *proid,int *cacheid,int type,int count){ + int i; + char *write_buf; + int write_len; + center_com_setpro *setpro; + + write_buf = create_combuf(CENTER_COMCODE_SETPRO,sizeof(center_com_setpro) * count,write_len,(void**)&setpro); + for(i = 0;i < count;i++){ + setpro[i].proid = proid[i]; + setpro[i].cacheid = cacheid[i]; + setpro[i].type = type; + } + writebytes(write_buf,write_len,NULL,NULL); + + return 0; +} +int server_conn::send_setjmod(char **jmod_name,int *cacheid,int type,int count){ + int i; + + char *write_buf; + int write_len; + center_com_setjmod *setjmod; + + write_buf = create_combuf(CENTER_COMCODE_SETJMOD,sizeof(center_com_setjmod) * count,write_len,(void**)&setjmod); + for(i = 0;i < count;i++){ + setjmod[i].jmod_name[0] = '\0'; + strncat(setjmod[i].jmod_name,jmod_name[i],sizeof(setjmod[i].jmod_name)); + setjmod[i].cacheid = cacheid[i]; + setjmod[i].type = type; + } + writebytes(write_buf,write_len,NULL,NULL); + + return 0; +} +int server_conn::readidle(){ + readbytes(new center_com_header,sizeof(center_com_header),recv_dispatch_fn,NULL); + return 0; +} +void server_conn::recv_dispatch(void *buf,size_t len,void *data){ + center_com_header *header; + char *readbuf; + + header = (center_com_header*)buf; + readbuf = new char[header->size]; + printf("code:%d size:%d\n",header->code,header->size); + switch(header->code){ + case CENTER_COMCODE_SETID: + readbytes(readbuf,header->size,recv_setid_fn,NULL); + break; + case CENTER_COMCODE_SUBMIT: + readbytes(readbuf,header->size,recv_submit_fn,NULL); + break; + case CENTER_COMCODE_SETPRO: + readbytes(readbuf,header->size,recv_setpro_fn,NULL); + break; + case CENTER_COMCODE_SENDPRO: + readbytes(readbuf,header->size,recv_sendpro_fn,NULL); + break; + case CENTER_COMCODE_SETJMOD: + readbytes(readbuf,header->size,recv_setjmod_fn,NULL); + break; + case CENTER_COMCODE_SENDJMOD: + readbytes(readbuf,header->size,recv_sendjmod_fn,NULL); + break; + case CENTER_COMCODE_SENDCODE: + readbytes(readbuf,header->size,recv_sendcode_fn,NULL); + break; + } + + delete header; +} +void server_conn::recv_setid(void *buf,size_t len,void *data){ + center_com_setid *setid; + + setid = (center_com_setid*)buf; + server_id = setid->id; + printf("server_id:%d\n",server_id); + + //judge server init + send_setinfo(); + + delete setid; +} +void server_conn::recv_submit(void *buf,size_t len,void *data){ + center_com_submit *sub; + char *write_buf; + int write_len; + center_com_reqcode *reqcode; + std::multimap::iterator sub_it; + char tpath[PATH_MAX + 1]; + struct stat st; + + sub = (center_com_submit*)buf; + if(server_codeconn == NULL){ + server_codeconn = server_connect(); + } + + if(server_submap.find(sub->subid) == server_submap.end()){ + snprintf(tpath,sizeof(tpath),"tmp/code/%d",sub->subid); + if(!stat(tpath,&st)){ + server_queuejudge(sub,tp_judge_thfn,tp_judge_cbfn); + }else{ + write_buf = create_combuf(CENTER_COMCODE_REQCODE,sizeof(center_com_submit),write_len,(void**)&reqcode); + reqcode->subid = sub->subid; + writebytes(write_buf,write_len,NULL,NULL); + server_submap.insert(std::pair(sub->subid,sub)); + } + }else{ + server_submap.insert(std::pair(sub->subid,sub)); + } +} +void server_conn::recv_setpro(void *buf,size_t len,void *data){ + int i; + int count; + center_com_setpro *setpro; + + char tpath[PATH_MAX + 1]; + FILE *f; + int cacheid; + std::vector sl_proid; + std::vector sl_cacheid; + + char *write_buf; + int write_len; + center_com_reqpro *reqpro; + + count = len / sizeof(center_com_setpro); + setpro = (center_com_setpro*)buf; + for(i = 0;i < count;i++){ + if(setpro[i].type == 0){ + snprintf(tpath,sizeof(tpath),"tmp/pro/%d/cacheinfo",setpro[i].proid); + f = fopen(tpath,"r"); + if(f != NULL){ + fscanf(f,"%d",&cacheid); + fclose(f); + + if(cacheid == setpro[i].cacheid){ + sl_proid.push_back(setpro[i].proid); + sl_cacheid.push_back(setpro[i].cacheid); + continue; + } + } + + if(server_fileconn == NULL){ + server_fileconn = server_connect(); + } + + write_buf = create_combuf(CENTER_COMCODE_REQPRO,sizeof(center_com_reqpro),write_len,(void**)&reqpro); + reqpro->proid = setpro[i].proid; + server_fileconn->writebytes(write_buf,write_len,NULL,NULL); + }else if(setpro[i].type == 1){ + + } + } + + if(!sl_proid.empty()){ + this->send_setpro(&sl_proid[0],&sl_cacheid[0],0,sl_proid.size()); + } + + delete setpro; +} +void server_conn::recv_sendpro(void *buf,size_t len,void *data){ + center_com_sendpro *sendpro; + char tpath[PATH_MAX + 1]; + int fd; + + sendpro = (center_com_sendpro*)buf; + snprintf(tpath,sizeof(tpath),"tmp/propack/%d.tar.bz2",sendpro->proid); + fd = open(tpath,O_WRONLY | O_CREAT,0644); + readfile(fd,sendpro->filesize,done_sendpro_fn,sendpro); +} +void server_conn::done_sendpro(void *buf,size_t len,void *data){ + center_com_sendpro *sendpro; + + close(*(int*)buf); + + sendpro = (center_com_sendpro*)data; + server_packtp->add(tp_unpackpro_thfn,sendpro,tp_unpackpro_cbfn,sendpro); +} +void server_conn::recv_setjmod(void *buf,size_t len,void *data){ + int i; + int count; + center_com_setjmod *setjmod; + + char tpath[PATH_MAX + 1]; + FILE *f; + int cacheid; + std::vector sl_jmod_name; + std::vector sl_cacheid; + + char *write_buf; + int write_len; + center_com_reqjmod *reqjmod; + + count = len / sizeof(center_com_setjmod); + setjmod = (center_com_setjmod*)buf; + for(i = 0;i < count;i++){ + if(setjmod[i].type == 0){ + snprintf(tpath,sizeof(tpath),"tmp/jmod/%s/cacheinfo",setjmod[i].jmod_name); + f = fopen(tpath,"r"); + if(f != NULL){ + fscanf(f,"%d",&cacheid); + fclose(f); + + if(cacheid == setjmod[i].cacheid){ + sl_jmod_name.push_back(setjmod[i].jmod_name); + sl_cacheid.push_back(setjmod[i].cacheid); + continue; + } + } + + if(server_fileconn == NULL){ + server_fileconn = server_connect(); + } + + write_buf = create_combuf(CENTER_COMCODE_REQJMOD,sizeof(center_com_reqjmod),write_len,(void**)&reqjmod); + reqjmod->jmod_name[0] = '\0'; + strncat(reqjmod->jmod_name,setjmod[i].jmod_name,sizeof(reqjmod->jmod_name)); + server_fileconn->writebytes(write_buf,write_len,NULL,NULL); + }else if(setjmod[i].type == 1){ + + } + } + + if(!sl_jmod_name.empty()){ + this->send_setjmod(&sl_jmod_name[0],&sl_cacheid[0],0,sl_jmod_name.size()); + } + + delete setjmod; +} +void server_conn::recv_sendjmod(void *buf,size_t len,void *data){ + center_com_sendjmod *sendjmod; + char tpath[PATH_MAX + 1]; + int fd; + + sendjmod = (center_com_sendjmod*)buf; + snprintf(tpath,sizeof(tpath),"tmp/jmodpack/%s.tar.bz2",sendjmod->jmod_name); + fd = open(tpath,O_WRONLY | O_CREAT,0644); + readfile(fd,sendjmod->filesize,done_sendjmod_fn,sendjmod); +} +void server_conn::done_sendjmod(void *buf,size_t len,void *data){ + center_com_sendjmod *sendjmod; + + close(*(int*)buf); + + sendjmod = (center_com_sendjmod*)data; + server_packtp->add(tp_unpackjmod_thfn,sendjmod,tp_unpackjmod_cbfn,sendjmod); +} +void server_conn::recv_sendcode(void *buf,size_t len,void *data){ + center_com_sendcode *sendcode; + char tpath[PATH_MAX + 1]; + int fd; + + sendcode = (center_com_sendcode*)buf; + snprintf(tpath,sizeof(tpath),"tmp/codepack/%d.tar.bz2",sendcode->subid); + fd = open(tpath,O_WRONLY | O_CREAT,0644); + readfile(fd,sendcode->filesize,done_sendcode_fn,sendcode); +} +void server_conn::done_sendcode(void *buf,size_t len,void *data){ + center_com_sendcode *sendcode; + + close(*(int*)buf); + + sendcode = (center_com_sendcode*)data; + server_packtp->add(tp_unpackcode_thfn,sendcode,tp_unpackcode_cbfn,sendcode); +} +void server_conn::tp_unpackpro_th(void *data){ + center_com_sendpro *sendpro; + char pack_path[PATH_MAX + 1]; + char dir_path[PATH_MAX + 1]; + char tpath[PATH_MAX + 1]; + FILE *f; + + sendpro = (center_com_sendpro*)data; + + snprintf(pack_path,sizeof(pack_path),"tmp/propack/%d.tar.bz2",sendpro->proid); + snprintf(dir_path,sizeof(dir_path),"tmp/pro/%d",sendpro->proid); + + mkdir(dir_path,0755); + server_cleardir(dir_path); + pack_unpack(pack_path,dir_path); + + snprintf(tpath,sizeof(tpath),"tmp/pro/%d/cacheinfo",sendpro->proid); + f = fopen(tpath,"w"); + fprintf(f,"%d",sendpro->cacheid); + fclose(f); +} +void server_conn::tp_unpackpro_cb(void *data){ + center_com_sendpro *sendpro; + + sendpro = (center_com_sendpro*)data; + send_setpro(&sendpro->proid,&sendpro->cacheid,0,1); + + delete sendpro; +} +void server_conn::tp_unpackjmod_th(void *data){ + center_com_sendjmod *sendjmod; + char pack_path[PATH_MAX + 1]; + char dir_path[PATH_MAX + 1]; + char tpath[PATH_MAX + 1]; + FILE *f; + + sendjmod = (center_com_sendjmod*)data; + + snprintf(pack_path,sizeof(pack_path),"tmp/jmodpack/%s.tar.bz2",sendjmod->jmod_name); + snprintf(dir_path,sizeof(dir_path),"tmp/jmod/%s",sendjmod->jmod_name); + mkdir(dir_path,0755); + server_cleardir(dir_path); + pack_unpack(pack_path,dir_path); + + snprintf(tpath,sizeof(tpath),"tmp/jmod/%s/cacheinfo",sendjmod->jmod_name); + f = fopen(tpath,"w"); + fprintf(f,"%d",sendjmod->cacheid); + fclose(f); +} +void server_conn::tp_unpackjmod_cb(void *data){ + center_com_sendjmod *sendjmod; + char *jmod_name; + + sendjmod = (center_com_sendjmod*)data; + jmod_name = sendjmod->jmod_name; + send_setjmod(&jmod_name,&sendjmod->cacheid,0,1); + + delete sendjmod; +} +void server_conn::tp_unpackcode_th(void *data){ + center_com_sendcode *sendcode; + char pack_path[PATH_MAX + 1]; + char dir_path[PATH_MAX + 1]; + char tpath[PATH_MAX + 1]; + FILE *f; + + sendcode = (center_com_sendcode*)data; + + snprintf(pack_path,sizeof(pack_path),"tmp/codepack/%d.tar.bz2",sendcode->subid); + snprintf(dir_path,sizeof(dir_path),"tmp/code/%d",sendcode->subid); + mkdir(dir_path,0755); + server_cleardir(dir_path); + pack_unpack(pack_path,dir_path); +} +void server_conn::tp_unpackcode_cb(void *data){ + center_com_sendcode *sendcode; + int subid; + std::multimap::iterator sub_it; + center_com_submit *sub; + + sendcode = (center_com_sendcode*)data; + subid = sendcode->subid; + + while((sub_it = server_submap.find(subid)) != server_submap.end()){ + sub = sub_it->second; + server_queuejudge(sub,tp_judge_thfn,tp_judge_cbfn); + server_submap.erase(sub_it); + } + + delete sendcode; +} +void server_conn::tp_judge_th(void *data){ + server_judgeth_info *th_info; + center_com_submit *sub; + char pro_path[PATH_MAX + 1]; + char code_path[PATH_MAX + 1]; + + th_info = (server_judgeth_info*)data; + sub = th_info->sub; + + snprintf(pro_path,sizeof(pro_path),"tmp/pro/%d",sub->proid); + snprintf(code_path,sizeof(code_path),"tmp/code/%d",sub->subid); + server_judge(sub->subid,pro_path,code_path,th_info->run_path,sub->lang,sub->set_data,th_info->res_data,th_info->res_len); +} +void server_conn::tp_judge_cb(void *data){ + server_judgeth_info *th_info; + center_com_submit *sub; + + th_info = (server_judgeth_info*)data; + sub = th_info->sub; + + send_result(sub->subid,th_info->res_data,th_info->res_len); + + th_info->use_flag = false; + th_info->sub = NULL; + delete sub; +} + + +static int server_queuejudge(center_com_submit *sub,tpool_protofn *th_fn,tpool_protofn *cb_fn){ + int i; + + printf("get submit %d %d\n",sub->subid,sub->proid); + for(i = 0;i < 8;i++){ + if(server_judgepool[i]->use_flag == false){ + server_judgepool[i]->use_flag = true; + server_judgepool[i]->sub = sub; + server_judgetp->add(th_fn,server_judgepool[i],cb_fn,server_judgepool[i]); + break; + } + } + + return 0; +} +static int server_judge(int subid,char *pro_path,char *code_path,char *run_path,int lang,char *set_data,char *res_data,size_t &res_len){ + judgm_line_info *line_info; + int pid; + + char tpath[PATH_MAX + 1]; + FILE *set_file; + char cwd_path[PATH_MAX + 1]; + char jmod_name[NAME_MAX + 1]; + char line_path[PATH_MAX + 1]; + char check_name[NAME_MAX + 1]; + char check_path[PATH_MAX + 1]; + char lchr; + char tchr; + + int judgk_modfd; + void *line_dll; + void *check_dll; + judgm_line_run_fn run_fn; + + snprintf(tpath,sizeof(tpath),"%s/setting",pro_path); + set_file = fopen(tpath,"r"); + + getcwd(cwd_path,sizeof(cwd_path)); + fscanf(set_file,"%s",jmod_name); + snprintf(line_path,sizeof(line_path),"%s/tmp/jmod/%s/%s_line.so",cwd_path,jmod_name,jmod_name); + fscanf(set_file,"%s",check_name); + snprintf(check_path,sizeof(check_path),"%s/tmp/jmod/%s/%s.so",cwd_path,jmod_name,check_name); + + lchr = '\n'; + while((tchr = fgetc(set_file)) != EOF){ + if(lchr == '\n' && tchr == '='){ + while(fgetc(set_file) != '\n'); + break; + } + lchr = tchr; + } + + judgk_modfd = open("/dev/judgk",O_RDWR); + line_dll = dlopen(line_path,RTLD_NOW); + check_dll = dlopen(check_path,RTLD_NOW); + + line_info = (judgm_line_info*)mmap(NULL,sizeof(struct judgm_line_info),PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS,-1,0); + + line_info->subid = subid; + + line_info->pro_path = pro_path; + line_info->code_path = code_path; + line_info->run_path = run_path; + + line_info->judgk_modfd = judgk_modfd; + line_info->line_dll = line_dll; + line_info->check_dll = check_dll; + + line_info->lang = lang; + line_info->set_file = set_file; + line_info->set_data = set_data; + + server_cleardir(line_info->run_path); + + run_fn = (judgm_line_run_fn)dlsym(line_dll,"run"); + if((pid = fork()) == 0){ + run_fn(line_info); + exit(0); + } + waitpid(pid,NULL,0); + + memcpy(res_data,line_info->res_data,line_info->res_len); + res_len = line_info->res_len; + + munmap(line_info,sizeof(judgm_line_info)); + fclose(set_file); + close(judgk_modfd); + return 0; +} +static int server_cleardir_callback(const char *path,const struct stat *st,int flag,struct FTW *ftw_buf){ + if(ftw_buf->level == 0){ + return 0; + } + + if(S_ISDIR(st->st_mode)){ + rmdir(path); + }else{ + unlink(path); + } + return 0; +} +static int server_cleardir(char *path){ + nftw(path,server_cleardir_callback,64,FTW_DEPTH | FTW_PHYS); + return 0; +} +static int server_addepev(int fd,unsigned int flag,int type,void *data){ + server_epevdata *epevdata; + epoll_event epev; + + epevdata = new server_epevdata(fd,type,data); + epev.events = flag; + epev.data.ptr = epevdata; + epoll_ctl(server_epfd,EPOLL_CTL_ADD,fd,&epev); + + return 0; +} +static int server_delepev(server_epevdata *epevdata){ + epoll_ctl(server_epfd,EPOLL_CTL_DEL,epevdata->fd,NULL); + delete epevdata; + return 0; +} +static server_conn* server_connect(){ + int cfd; + sockaddr_in caddr; + epoll_event epev; + server_conn *cinfo; + + cfd = socket(AF_INET,SOCK_STREAM | SOCK_NONBLOCK,6); + caddr.sin_family = AF_INET; + caddr.sin_port = htons(SERVER_JUDGE_PORT); + //caddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + caddr.sin_addr.s_addr = inet_addr("10.8.0.2"); + + cinfo = new server_conn(cfd); + server_addepev(cfd,EPOLLIN | EPOLLOUT | EPOLLRDHUP | EPOLLET,SERVER_EPEV_JUDGECLIENT,cinfo); + connect(cfd,(sockaddr*)&caddr,sizeof(caddr)); + + return cinfo; +} +int main(){ + int i; + + epoll_event epev; + epoll_event epevs[SERVER_EPOLL_MAXEVENT]; + int nevs; + + int ev_flag; + server_epevdata *epevdata; + server_conn *cinfo; + tpool *tpinfo; + + signal(SIGPIPE,SIG_IGN); + server_epfd = epoll_create1(0); + + server_id = 0; + server_avail = 2; + server_mainconn = server_connect(); + server_fileconn = NULL; + server_codeconn = NULL; + + server_packtp = new tpool(4); + server_packtp->start(); + server_addepev(server_packtp->fd,EPOLLIN | EPOLLET,SERVER_EPEV_TPOOL,server_packtp); + + for(i = 0;i < 8;i++){ + server_judgepool[i] = new server_judgeth_info(i); + } + server_judgetp = new tpool(8); + server_judgetp->start(); + server_addepev(server_judgetp->fd,EPOLLIN | EPOLLET,SERVER_EPEV_TPOOL,server_judgetp); + + while(true){ + nevs = epoll_wait(server_epfd,epevs,SERVER_EPOLL_MAXEVENT,-1); + for(i = 0;i < nevs;i++){ + ev_flag = epevs[i].events; + epevdata = (server_epevdata*)epevs[i].data.ptr; + + if(epevdata->type == SERVER_EPEV_JUDGECLIENT){ + cinfo = (server_conn*)epevdata->data; + if(ev_flag & EPOLLIN){ + cinfo->readio(); + } + if(ev_flag & EPOLLOUT){ + cinfo->writeio(); + } + + server_packtp->done(); + }else if(epevdata->type = SERVER_EPEV_TPOOL){ + tpinfo = (tpool*)epevdata->data; + if(ev_flag & EPOLLIN){ + tpinfo->done(); + } + } + } + } + + close(server_epfd); + + return 0; +} diff --git a/toj/center/src/judge_server.h b/toj/center/src/judge_server.h new file mode 100644 index 0000000..d904d9d --- /dev/null +++ b/toj/center/src/judge_server.h @@ -0,0 +1,107 @@ +#define SERVER_JUDGE_PORT 2573 +#define SERVER_EPOLL_MAXEVENT 4096 + +#define SERVER_EPEV_JUDGECLIENT 0 +#define SERVER_EPEV_TPOOL 1 +class server_epevdata{ +public: + int fd; + int type; + void *data; + + server_epevdata(int fd,int type,void *data); +}; + +class server_conn : public netio{ +private: + netio_iofn *recv_dispatch_fn; + netio_iofn *recv_setid_fn; + netio_iofn *recv_submit_fn; + netio_iofn *recv_setpro_fn; + netio_iofn *recv_sendpro_fn; + netio_iofn *done_sendpro_fn; + netio_iofn *recv_setjmod_fn; + netio_iofn *recv_sendjmod_fn; + netio_iofn *done_sendjmod_fn; + netio_iofn *recv_sendcode_fn; + netio_iofn *done_sendcode_fn; + tpool_fn *tp_unpackpro_thfn; + tpool_fn *tp_unpackpro_cbfn; + tpool_fn *tp_unpackjmod_thfn; + tpool_fn *tp_unpackjmod_cbfn; + tpool_fn *tp_unpackcode_thfn; + tpool_fn *tp_unpackcode_cbfn; + tpool_fn *tp_judge_thfn; + tpool_fn *tp_judge_cbfn; + + char* create_combuf(int code,int size,int &len,void **data); + void recv_dispatch(void *buf,size_t len,void *data); + void recv_setid(void *buf,size_t len,void *data); + void recv_submit(void *buf,size_t len,void *data); + void recv_setpro(void *buf,size_t len,void *data); + void recv_sendpro(void *buf,size_t len,void *data); + void done_sendpro(void *buf,size_t len,void *data); + void recv_setjmod(void *buf,size_t len,void *data); + void recv_sendjmod(void *buf,size_t len,void *data); + void done_sendjmod(void *buf,size_t len,void *data); + void recv_sendcode(void *buf,size_t len,void *data); + void done_sendcode(void *buf,size_t len,void *data); + void tp_unpackpro_th(void *data); + void tp_unpackpro_cb(void *data); + void tp_unpackjmod_th(void *data); + void tp_unpackjmod_cb(void *data); + void tp_unpackcode_th(void *data); + void tp_unpackcode_cb(void *data); + void tp_judge_th(void *data); + void tp_judge_cb(void *data); + +public: + server_conn(int fd); + int send_setid(); + int send_setinfo(); + int send_result(int subid,char *res_data,size_t res_len); + int send_setpro(int *proid,int *cacheid,int type,int count); + int send_setjmod(char **jmod_name,int *cacheid,int type,int count); + virtual int readidle(); +}; + +class server_judgeth_info{ +public: + bool use_flag; + int thid; + char run_path[PATH_MAX + 1]; + center_com_submit *sub; + char res_data[JUDGE_RES_DATAMAX]; + size_t res_len; + + server_judgeth_info(int thid){ + this->use_flag = false; + this->thid = thid; + snprintf(this->run_path,sizeof(this->run_path),"tmp/run/%d",thid); + mkdir(this->run_path,0775); + this->sub = NULL; + this->res_len = 0; + } +}; + +static int server_queuejudge(center_com_submit *sub,tpool_protofn *th_fn,tpool_protofn *cb_fn); +static int server_judge(int subid,char *pro_path,char *code_path,char *run_path,int lang,char *set_data,char *res_data,size_t &res_len); +static int server_cleardir_callback(const char *path,const struct stat *st,int flag,struct FTW *ftw_buf); +static int server_cleardir(char *path); +static int server_addepev(int fd,unsigned int flag,int type,void *data); +static int server_delepev(server_epevdata *epevdata); +static server_conn* server_connect(); + +static int server_id; +static int server_avail; +static std::multimap server_submap; +static int server_epfd; +static server_conn *server_mainconn; +static server_conn *server_fileconn; +static server_conn *server_codeconn; +static tpool *server_packtp; +static server_judgeth_info *server_judgepool[8]; +static tpool *server_judgetp; + +extern int pack_pack(char *pack_path,char *dir_path); +extern int pack_unpack(char *pack_path,char *dir_path); diff --git a/toj/center/src/judgk.h b/toj/center/src/judgk.h new file mode 100755 index 0000000..18f9a6c --- /dev/null +++ b/toj/center/src/judgk.h @@ -0,0 +1,16 @@ +struct judgk_proc_info{ + struct hlist_node node; + struct list_head list; + + struct task_struct *task; + struct file *std_in; + struct file *std_out; + char run_path[PATH_MAX + 1]; + int status; + unsigned long timelimit; + unsigned long jiff_start; + unsigned long jiff_end; + unsigned long memlimit; + unsigned long runtime; + unsigned long memory; +}; diff --git a/toj/center/src/judgk_com.h b/toj/center/src/judgk_com.h new file mode 100644 index 0000000..842c69c --- /dev/null +++ b/toj/center/src/judgk_com.h @@ -0,0 +1,25 @@ +#define IOCTL_PROC_ADD _IOWR('x',0x0,int) +#define IOCTL_PROC_GET _IOWR('x',0x1,int) +#define IOCTL_PROC_DEL _IOR('x',0x3,int) + +#define IOCTL_HYPERIO_ADD _IOWR('x',0x10,int) +#define IOCTL_HYPERIO_READ _IOWR('x',0x11,int) +#define IOCTL_HYPERIO_WRITE _IOWR('x',0x12,int) +#define IOCTL_HYPERIO_DEL _IOWR('x',0x13,int) + +#define JUDGK_COM_HYPERIO_BUFSIZE 4194304 + +struct judgk_com_proc_add{ + char run_path[PATH_MAX + 1]; + pid_t pid; + unsigned long kern_task; + unsigned long timelimit; + unsigned long hardtimelimit; + unsigned long memlimit; +}; +struct judgk_com_proc_get{ + unsigned long kern_task; + int status; + unsigned long runtime; + unsigned long memory; +}; diff --git a/toj/center/src/judgk_hyperio.c b/toj/center/src/judgk_hyperio.c new file mode 100644 index 0000000..67b0ef6 --- /dev/null +++ b/toj/center/src/judgk_hyperio.c @@ -0,0 +1,417 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include"judgk.h" +#include"judgk_com.h" +#include"judgk_hyperio.h" + +int judgk_hyperio_init(){ + int i; + struct hyperio_info *info; + + hyperio_filp_ht = (struct hlist_head*)kmalloc(sizeof(struct hlist_head) * HYPERIO_FILP_HTSIZE,GFP_KERNEL); + for(i = 0;i < HYPERIO_FILP_HTSIZE;i++){ + INIT_HLIST_HEAD(&hyperio_filp_ht[i]); + } + + hyperio_table = (struct hyperio_info*)kmalloc(sizeof(struct hyperio_info) * HYPERIO_MAXNUM,GFP_KERNEL); + for(i = 0;i < HYPERIO_MAXNUM;i++){ + info = &hyperio_table[i]; + + atomic_set(&info->ref_count,0); + info->filp = NULL; + info->create_flag = false; + info->end_flag = false; + info->hook_fops = NULL; + info->old_fops = NULL; + + atomic64_set(&info->read_remain,JUDGK_COM_HYPERIO_BUFSIZE); + info->read_off = 0; + info->read_buf = NULL; + init_completion(&info->read_rwait); + init_completion(&info->read_wwait); + + atomic64_set(&info->write_remain,JUDGK_COM_HYPERIO_BUFSIZE); + info->write_off = 0; + info->write_buf = NULL; + init_completion(&info->write_rwait); + init_completion(&info->write_wwait); + } + + hyperio_tty_drv = tty_alloc_driver(HYPERIO_MAXNUM,TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV); + hyperio_tty_drv->owner = THIS_MODULE; + hyperio_tty_drv->driver_name = "judgk_tty"; + hyperio_tty_drv->name = "jtty"; + hyperio_tty_drv->type = TTY_DRIVER_TYPE_SYSTEM; + hyperio_tty_drv->subtype = SYSTEM_TYPE_TTY; + hyperio_tty_drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; + hyperio_tty_drv->init_termios = tty_std_termios; + hyperio_tty_drv->init_termios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); + hyperio_tty_drv->init_termios.c_oflag &= ~OPOST; + hyperio_tty_drv->init_termios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); + hyperio_tty_drv->init_termios.c_cflag &= ~(CSIZE | PARENB); + hyperio_tty_drv->init_termios.c_cflag |= CS8; + tty_set_operations(hyperio_tty_drv,&hyperio_tops); + + tty_register_driver(hyperio_tty_drv); + + return 0; +} +int judgk_hyperio_exit(){ + int i; + + for(i = 0;i < HYPERIO_MAXNUM;i++){ + if(hyperio_table[i].create_flag == true){ + tty_unregister_device(hyperio_tty_drv,i); + hyperio_table[i].create_flag = false; + } + } + tty_unregister_driver(hyperio_tty_drv); + + return 0; +} +int judgk_hyperio_add(struct file *filp){ + int idx; + struct hyperio_info *info; + + info = NULL; + for(idx = 0;idx < HYPERIO_MAXNUM;idx++){ + if(atomic_cmpxchg(&hyperio_table[idx].ref_count,0,1) == 0){ + info = &hyperio_table[idx]; + break; + } + } + if(info == NULL){ + return -1; + } + + filp->private_data = info; + + info->filp = NULL; + if(info->create_flag == false){ + tty_port_init(&info->port); + tty_port_register_device(&info->port,hyperio_tty_drv,idx,NULL); + info->create_flag = true; + } + info->end_flag = false; + if(info->hook_fops == NULL){ + info->hook_fops = (struct file_operations*)kmalloc(sizeof(struct file_operations),GFP_KERNEL); + } + + atomic64_set(&info->read_remain,JUDGK_COM_HYPERIO_BUFSIZE); + info->read_off = 0; + if(info->read_buf == NULL){ + info->read_buf = kmalloc(JUDGK_COM_HYPERIO_BUFSIZE,GFP_KERNEL); + } + memset(info->read_buf,0,JUDGK_COM_HYPERIO_BUFSIZE); + init_completion(&info->read_rwait); + init_completion(&info->read_wwait); + + atomic64_set(&info->write_remain,JUDGK_COM_HYPERIO_BUFSIZE); + info->write_off = 0; + if(info->write_buf == NULL){ + info->write_buf = kmalloc(JUDGK_COM_HYPERIO_BUFSIZE,GFP_KERNEL); + } + memset(info->write_buf,0,JUDGK_COM_HYPERIO_BUFSIZE); + init_completion(&info->write_rwait); + init_completion(&info->write_wwait); + + return idx; +} +int judgk_hyperio_read(struct file *filp,size_t len){ + struct hyperio_info *info; + bool wait_flag; + size_t remain; + + if((long)len >= 0){ + wait_flag = true; + }else{ + wait_flag = false; + len = -(long)len; + } + + info = (struct hyperio_info*)filp->private_data; + + remain = atomic64_read(&info->write_remain); + if(unlikely(len > (JUDGK_COM_HYPERIO_BUFSIZE - remain))){ + return -EINVAL; + } + + if(unlikely(len > 0 && (remain = atomic64_add_return(len,&info->write_remain)) == len)){ + complete(&info->write_wwait); + } + if(wait_flag == true){ + while(unlikely(remain == JUDGK_COM_HYPERIO_BUFSIZE)){ + if(info->end_flag == true){ + remain = atomic64_read(&info->write_remain); + break; + } + wait_for_completion_interruptible(&info->write_rwait); + remain = atomic64_read(&info->write_remain); + } + } + + return JUDGK_COM_HYPERIO_BUFSIZE - remain; +} +int judgk_hyperio_write(struct file *filp,size_t len){ + struct hyperio_info *info; + bool wait_flag; + size_t remain; + + if((long)len >= 0){ + wait_flag = true; + }else{ + wait_flag = false; + len = -(long)len; + } + + info = (struct hyperio_info*)filp->private_data; + + remain = atomic64_read(&info->read_remain); + if(unlikely(len > remain)){ + return -EINVAL; + } + + if(unlikely(len > 0 && (remain = atomic64_sub_return(len,&info->read_remain)) == (JUDGK_COM_HYPERIO_BUFSIZE - len))){ + complete(&info->read_rwait); + } + if(wait_flag == true){ + while(unlikely(remain == 0)){ + if(info->end_flag == true){ + remain = atomic64_read(&info->read_remain); + break; + } + wait_for_completion_interruptible(&info->read_wwait); + remain = atomic64_read(&info->read_remain); + } + } + + return remain; +} +int judgk_hyperio_del(struct file *filp){ + struct hyperio_info *info; + + info = (struct hyperio_info*)filp->private_data; + info->end_flag = true; + complete(&info->read_rwait); + complete(&info->read_wwait); + complete(&info->write_rwait); + complete(&info->write_wwait); + + atomic_dec(&info->ref_count); + return 0; +} +int judgk_hyperio_mmap(struct file *filp,struct vm_area_struct *vma){ + unsigned long size; + unsigned long off; + void *buf; + + size = vma->vm_end - vma->vm_start; + off = vma->vm_pgoff << PAGE_SHIFT; + if((size + off) > JUDGK_COM_HYPERIO_BUFSIZE){ + return -EINVAL; + } + if((vma->vm_flags & VM_READ) != 0 && (vma->vm_flags & VM_WRITE) != 0){ + return -EINVAL; + } + if((vma->vm_flags & VM_READ) == 0 && (vma->vm_flags & VM_WRITE) == 0){ + return -EINVAL; + } + + if((vma->vm_flags & VM_READ) != 0){ + buf = ((struct hyperio_info*)filp->private_data)->write_buf; + }else{ + buf = ((struct hyperio_info*)filp->private_data)->read_buf; + } + remap_pfn_range(vma, + vma->vm_start, + virt_to_phys(buf + off) >> PAGE_SHIFT, + size, + vma->vm_page_prot); + + return 0; +} + +static inline struct hyperio_info* hyperio_filp_lookup(struct file *filp){ + struct hlist_node *node; + struct hyperio_info *info; + + rcu_read_lock(); + + info = NULL; + hlist_for_each_entry_rcu(info,node,&hyperio_filp_ht[(unsigned long)filp % HYPERIO_FILP_HTSIZE],node){ + if((unsigned long)info->filp == (unsigned long)filp){ + break; + } + info = NULL; + } + + rcu_read_unlock(); + + return info; +} +static int hyperio_tty_open(struct tty_struct *tty, struct file *filp){ + struct hyperio_info *info; + struct file_operations *hook_fops; + + tty->low_latency = 1; + + info = &hyperio_table[tty->index]; + atomic_inc(&info->ref_count); + info->filp = filp; + + hook_fops = info->hook_fops; + info->old_fops = filp->f_op; + memcpy(hook_fops,filp->f_op,sizeof(struct file_operations)); + + hook_fops->read = hyperio_tty_filpread; + hook_fops->write = hyperio_tty_filpwrite; + + filp->f_op = hook_fops; + + spin_lock(&hyperio_filp_htlock); + + hlist_add_head_rcu(&info->node,&hyperio_filp_ht[(unsigned long)info->filp % HYPERIO_FILP_HTSIZE]); + + spin_unlock(&hyperio_filp_htlock); + + return 0; +} +static void hyperio_tty_close(struct tty_struct *tty, struct file *filp){ + struct hyperio_info *info; + + info = &hyperio_table[tty->index]; + + spin_lock(&hyperio_filp_htlock); + + hlist_del_rcu(&info->node); + + spin_unlock(&hyperio_filp_htlock); + + filp->f_op = info->old_fops; + + info->end_flag = true; + complete(&info->read_rwait); + complete(&info->read_wwait); + complete(&info->write_rwait); + complete(&info->write_wwait); + + atomic_dec(&info->ref_count); +} +static int hyperio_tty_write(struct tty_struct *tty,const unsigned char *buf,int count){ + return count; +} +static int hyperio_tty_write_room(struct tty_struct *tty){ + return JUDGK_COM_HYPERIO_BUFSIZE; +} +static ssize_t hyperio_tty_filpread(struct file *filp,char __user *buf,size_t count,loff_t *off){ + struct hyperio_info *info; + size_t buf_len; + off_t buf_off; + size_t remain; + size_t read_len; + off_t read_off; + + if(unlikely(count < 0)){ + return -EINVAL; + } + + info = hyperio_filp_lookup(filp); + if(unlikely(info == NULL)){ + return -EIO; + } + + buf_len = count; + buf_off = 0; + while(likely(buf_len > 0)){ + while(unlikely((remain = atomic64_read(&info->read_remain)) == JUDGK_COM_HYPERIO_BUFSIZE)){ + if(unlikely(info->end_flag == true)){ + return -EIO; + } + if(likely(buf_off > 0)){ + return buf_off; + } + wait_for_completion_interruptible(&info->read_rwait); + } + if(unlikely(buf_len > (JUDGK_COM_HYPERIO_BUFSIZE - remain))){ + read_len = JUDGK_COM_HYPERIO_BUFSIZE - remain; + }else{ + read_len = buf_len; + } + + read_off = info->read_off; + if(likely((read_len + read_off) < JUDGK_COM_HYPERIO_BUFSIZE)){ + copy_to_user(buf + buf_off,info->read_buf + read_off,read_len); + info->read_off = read_len + read_off; + }else{ + copy_to_user(buf + buf_off,info->read_buf + read_off,JUDGK_COM_HYPERIO_BUFSIZE - read_off); + copy_to_user(buf + buf_off + (JUDGK_COM_HYPERIO_BUFSIZE - read_off),info->read_buf,(read_len + read_off) - JUDGK_COM_HYPERIO_BUFSIZE); + info->read_off = (read_len + read_off) - JUDGK_COM_HYPERIO_BUFSIZE; + } + + if(unlikely(atomic64_add_return(read_len,&info->read_remain) == read_len)){ + complete(&info->read_wwait); + } + buf_len -= read_len; + buf_off += read_len; + } + + return count; +} +static ssize_t hyperio_tty_filpwrite(struct file *filp,const char __user *buf,size_t count,loff_t *off){ + struct hyperio_info *info; + size_t buf_len; + off_t buf_off; + size_t remain; + size_t write_len; + off_t write_off; + + if(unlikely(count < 0)){ + return -EINVAL; + } + + info = hyperio_filp_lookup(filp); + if(unlikely(info == NULL)){ + return -EIO; + } + + buf_len = count; + buf_off = 0; + while(likely(buf_len > 0)){ + while(unlikely((remain = atomic64_read(&info->write_remain)) == 0)){ + if(unlikely(info->end_flag == true)){ + return -EIO; + } + wait_for_completion_interruptible(&info->write_wwait); + } + if(unlikely(buf_len > remain)){ + write_len = remain; + }else{ + write_len = buf_len; + } + + write_off = info->write_off; + if(unlikely((write_len + write_off) >= JUDGK_COM_HYPERIO_BUFSIZE)){ + copy_from_user(info->write_buf + write_off,buf + buf_off,JUDGK_COM_HYPERIO_BUFSIZE - write_off); + copy_from_user(info->write_buf,buf + buf_off + (JUDGK_COM_HYPERIO_BUFSIZE - write_off),(write_len + write_off) - JUDGK_COM_HYPERIO_BUFSIZE); + info->write_off = (write_len + write_off) - JUDGK_COM_HYPERIO_BUFSIZE; + }else{ + copy_from_user(info->write_buf + write_off,buf + buf_off,write_len); + info->write_off = write_len + write_off; + } + + if(unlikely(atomic64_sub_return(write_len,&info->write_remain) == (JUDGK_COM_HYPERIO_BUFSIZE - write_len))){ + complete(&info->write_rwait); + } + buf_len -= write_len; + buf_off += write_len; + } + + return count; +} diff --git a/toj/center/src/judgk_hyperio.h b/toj/center/src/judgk_hyperio.h new file mode 100644 index 0000000..ccc1449 --- /dev/null +++ b/toj/center/src/judgk_hyperio.h @@ -0,0 +1,53 @@ +#define HYPERIO_MAXNUM 256 +#define HYPERIO_FILP_HTSIZE 1009 + +struct hyperio_info{ + atomic_t ref_count; + struct hlist_node node; + struct file *filp; + struct tty_port port; + + bool create_flag; + bool end_flag; + struct file_operations *hook_fops; + const struct file_operations *old_fops; + + atomic64_t read_remain; + off_t read_off; + char *read_buf; + struct completion read_rwait; + struct completion read_wwait; + + atomic64_t write_remain; + off_t write_off; + char *write_buf; + struct completion write_rwait; + struct completion write_wwait; +}; + +static inline struct hyperio_info* hyperio_filp_lookup(struct file *filp); +static int hyperio_tty_open(struct tty_struct * tty, struct file * filp); +static void hyperio_tty_close(struct tty_struct * tty, struct file * filp); +static int hyperio_tty_write(struct tty_struct *tty,const unsigned char *buf,int count); +static int hyperio_tty_write_room(struct tty_struct *tty); +static ssize_t hyperio_tty_filpread(struct file *filp,char __user *buf,size_t count,loff_t *off); +static ssize_t hyperio_tty_filpwrite(struct file *filp,const char __user *buf,size_t count,loff_t *off); + +static struct tty_driver *hyperio_tty_drv; +static struct tty_operations hyperio_tops = { + .open = hyperio_tty_open, + .close = hyperio_tty_close, + .write = hyperio_tty_write, + .write_room = hyperio_tty_write_room +}; +static struct hyperio_info *hyperio_table; +static struct hlist_head *hyperio_filp_ht; +static DEFINE_SPINLOCK(hyperio_filp_htlock); + +int judgk_hyperio_init(void); +int judgk_hyperio_exit(void); +int judgk_hyperio_add(struct file *filp); +int judgk_hyperio_read(struct file *filp,size_t len); +int judgk_hyperio_write(struct file *filp,size_t len); +int judgk_hyperio_del(struct file *filp); +int judgk_hyperio_mmap(struct file *filp,struct vm_area_struct *vma); diff --git a/toj/center/src/judgk_mod.c b/toj/center/src/judgk_mod.c new file mode 100755 index 0000000..3f56d90 --- /dev/null +++ b/toj/center/src/judgk_mod.c @@ -0,0 +1,75 @@ +#include +#include +#include +#include +#include +#include +#include + +#include"judgk.h" +#include"judgk_com.h" +#include"judgk_mod.h" + +static int __init mod_init(){ + alloc_chrdev_region(&mod_dev,0,1,"judgk"); + mod_class = class_create(THIS_MODULE,"chardev"); + device_create(mod_class,NULL,mod_dev,NULL,"judgk"); + cdev_init(&mod_cdev,&mod_fops); + cdev_add(&mod_cdev,mod_dev,1); + + judgk_proc_init(); + judgk_security_hook(); + judgk_syscall_hook(); + judgk_hyperio_init(); + + pr_alert("judgk:Init\n"); + return 0; +} +static void __exit mod_exit(){ + cdev_del(&mod_cdev); + device_destroy(mod_class,mod_dev); + class_destroy(mod_class); + unregister_chrdev_region(mod_dev,1); + + judgk_proc_exit(); + judgk_syscall_unhook(); + judgk_security_unhook(); + judgk_hyperio_exit(); + + schedule_timeout_interruptible(3 * HZ); + pr_alert("judgk:Exit\n"); +} +module_init(mod_init); +module_exit(mod_exit); +MODULE_LICENSE("GPL"); + +static long mod_ioctl(struct file *filp,unsigned int cmd,unsigned long arg){ + int ret; + + ret = -1; + switch(cmd){ + case IOCTL_PROC_ADD: + ret = judgk_proc_add(arg); + break; + case IOCTL_PROC_GET: + ret = judgk_proc_get(arg); + break; + case IOCTL_PROC_DEL: + ret = judgk_proc_del(arg); + break; + case IOCTL_HYPERIO_ADD: + ret = judgk_hyperio_add(filp); + break; + case IOCTL_HYPERIO_READ: + ret = judgk_hyperio_read(filp,arg); + break; + case IOCTL_HYPERIO_WRITE: + ret = judgk_hyperio_write(filp,arg); + break; + case IOCTL_HYPERIO_DEL: + ret = judgk_hyperio_del(filp); + break; + } + + return ret; +} diff --git a/toj/center/src/judgk_mod.h b/toj/center/src/judgk_mod.h new file mode 100755 index 0000000..58bc76b --- /dev/null +++ b/toj/center/src/judgk_mod.h @@ -0,0 +1,31 @@ +static int __init mod_init(void); +static void __exit mod_exit(void); +static long mod_ioctl(struct file *filp,unsigned int cmd,unsigned long arg); + +static dev_t mod_dev; +static struct cdev mod_cdev; +static struct class *mod_class; + +extern int judgk_hyperio_mmap(struct file *filp,struct vm_area_struct *vma); +static struct file_operations mod_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = mod_ioctl, + .mmap = judgk_hyperio_mmap +}; + +extern int judgk_proc_init(void); +extern int judgk_proc_exit(void); +extern int judgk_proc_add(unsigned long arg); +extern int judgk_proc_get(unsigned long arg); +extern int judgk_proc_del(unsigned long arg); +extern int judgk_syscall_hook(void); +extern int judgk_syscall_unhook(void); +extern int judgk_security_hook(void); +extern int judgk_security_unhook(void); + +extern int judgk_hyperio_init(void); +extern int judgk_hyperio_exit(void); +extern int judgk_hyperio_add(struct file *filp); +extern int judgk_hyperio_read(struct file *filp,size_t len); +extern int judgk_hyperio_write(struct file *filp,size_t len); +extern int judgk_hyperio_del(struct file *filp); diff --git a/toj/center/src/judgk_proc.c b/toj/center/src/judgk_proc.c new file mode 100755 index 0000000..17a0375 --- /dev/null +++ b/toj/center/src/judgk_proc.c @@ -0,0 +1,251 @@ +#include +#include +#include +#include +#include +#include + +#include"judge_def.h" +#include"judgk.h" +#include"judgk_com.h" +#include"judgk_proc.h" + +int judgk_proc_init(){ + int i; + + proc_task_ht = kmalloc(sizeof(struct hlist_head) * PROC_TASK_HTSIZE,GFP_KERNEL); + for(i = 0;i < PROC_TASK_HTSIZE;i++){ + INIT_HLIST_HEAD(&proc_task_ht[i]); + } + proc_info_cachep = kmem_cache_create("proc_info_cachep",sizeof(struct judgk_proc_info),0,0,NULL); + + proc_watcher_task = kthread_run(proc_watcher,NULL,"judgk_proc"); + + return 0; +} +int judgk_proc_exit(){ + kthread_stop(proc_watcher_task); + return 0; +} + +int judgk_proc_add(unsigned long arg){ + int ret; + + struct task_struct *task; + struct judgk_proc_info *info; + struct judgk_com_proc_add *com_proc_add; + + ret = 0; + com_proc_add = kmalloc(sizeof(struct judgk_com_proc_add),GFP_KERNEL); + copy_from_user(com_proc_add,(void* __user)arg,sizeof(struct judgk_com_proc_add)); + + if((task = get_pid_task(find_vpid(com_proc_add->pid),PIDTYPE_PID)) == NULL){ + ret = -1; + goto end; + } + if(judgk_proc_task_lookup(task) != NULL){ + put_task_struct(task); + ret = -1; + goto end; + } + + info = kmem_cache_alloc(proc_info_cachep,GFP_KERNEL); + info->task = task; + info->std_in = fcheck_files(task->files,0); + info->std_out = fcheck_files(task->files,1); + info->status = JUDGE_AC; + info->timelimit = com_proc_add->timelimit; + info->jiff_start = jiffies; + info->jiff_end = info->jiff_start + usecs_to_jiffies(com_proc_add->hardtimelimit); + info->memlimit = com_proc_add->memlimit; + info->runtime = 0L; + info->memory = 0L; + + if(proc_get_path(com_proc_add->run_path,info->run_path)){ + put_task_struct(task); + kmem_cache_free(proc_info_cachep,info); + + ret = -1; + goto end; + } + proc_close_fd(task); + + spin_lock(&proc_task_htlock); + + list_add_rcu(&info->list,&proc_task_list); + hlist_add_head_rcu(&info->node,&proc_task_ht[(unsigned long)info->task % PROC_TASK_HTSIZE]); + + spin_unlock(&proc_task_htlock); + + com_proc_add->kern_task = (unsigned long)task; + copy_to_user((void* __user)arg,com_proc_add,sizeof(struct judgk_com_proc_add)); + +end: + + kfree(com_proc_add); + + return ret; +} +int judgk_proc_get(unsigned long arg){ + struct task_struct *task; + struct judgk_proc_info *info; + struct judgk_com_proc_get *com_proc_get; + + com_proc_get = kmalloc(sizeof(struct judgk_com_proc_get),GFP_KERNEL); + copy_from_user(com_proc_get,(void* __user)arg,sizeof(struct judgk_com_proc_get)); + task = (struct task_struct*)com_proc_get->kern_task; + if((info = judgk_proc_task_lookup(task)) == NULL){ + kfree(com_proc_get); + return -1; + } + + com_proc_get->status = info->status; + if(info->runtime > 0L){ + com_proc_get->runtime = info->runtime; + }else{ + com_proc_get->runtime = cputime_to_usecs(task->utime); + info->runtime = com_proc_get->runtime; + } + com_proc_get->memory = info->memory; + + copy_to_user((void* __user)arg,com_proc_get,sizeof(struct judgk_com_proc_get)); + kfree(com_proc_get); + + spin_lock(&proc_task_htlock); + + list_del_rcu(&info->list); + hlist_del_rcu(&info->node); + + spin_unlock(&proc_task_htlock); + + synchronize_rcu(); + + put_task_struct(info->task); + kmem_cache_free(proc_info_cachep,info); + + return 0; +} +int judgk_proc_del(unsigned long arg){ + struct task_struct *task; + struct judgk_proc_info *info; + + task = (struct task_struct*)arg; + if((info = judgk_proc_task_lookup(task)) == NULL){ + return -1; + } + + spin_lock(&proc_task_htlock); + + list_del_rcu(&info->list); + hlist_del_rcu(&info->node); + + spin_unlock(&proc_task_htlock); + + synchronize_rcu(); + + put_task_struct(info->task); + kmem_cache_free(proc_info_cachep,info); + + return 0; +} +struct judgk_proc_info* judgk_proc_task_lookup(struct task_struct *task){ + struct judgk_proc_info *info; + struct hlist_node *node; + + rcu_read_lock(); + + info = NULL; + hlist_for_each_entry_rcu(info,node,&proc_task_ht[(unsigned long)task % PROC_TASK_HTSIZE],node){ + if((unsigned long)info->task == (unsigned long)task){ + break; + } + info = NULL; + } + + rcu_read_unlock(); + + return info; +} + +static int proc_watcher(void *data){ + struct judgk_proc_info *info; + + while(!kthread_should_stop()){ + + rcu_read_lock(); + + list_for_each_entry_rcu(info,&proc_task_list,list){ + if(cputime_to_usecs(info->task->utime) > info->timelimit){ + pr_alert("judgk:TLE"); + info->status = JUDGE_TLE; + send_sig(SIGKILL,info->task,0); + }else if(time_after(jiffies,info->jiff_end)){ + info->runtime = jiffies_to_usecs((unsigned long)(-((long)info->jiff_start - (long)jiffies))); + info->status = JUDGE_TLE; + send_sig(SIGKILL,info->task,0); + } + } + + rcu_read_unlock(); + + schedule_timeout_interruptible(HZ / 2); + } + + return 0; +} +static int proc_get_path(char *in_path,char *real_path){ + struct file *f; + char *buf_path; + + if(IS_ERR(f = filp_open(in_path,O_RDONLY,0))){ + return -1; + } + + buf_path = kmalloc(sizeof(char) * (PATH_MAX + 1),GFP_KERNEL); + real_path[0] = '\0'; + strncat(real_path,d_path(&f->f_path,buf_path,PATH_MAX + 1),PATH_MAX + 1); + kfree(buf_path); + filp_close(f,NULL); + + return 0; +} +//Watch out kernel update +static int proc_close_fd(struct task_struct *task){ + struct file *f; + struct files_struct *files; + struct fdtable *fdt; + int fd; + + files = task->files; + + spin_lock(&files->file_lock); + + fdt = files_fdtable(files); + for(fd = 3;fd < fdt->max_fds;fd++){ + if((fd = find_next_bit(fdt->open_fds,fdt->max_fds,fd)) >= fdt->max_fds){ + break; + } + f = fdt->fd[fd]; + if(f == NULL){ + continue; + } + + rcu_assign_pointer(fdt->fd[fd],NULL); + __clear_bit(fd,fdt->close_on_exec); + __clear_bit(fd,fdt->open_fds); + if(fd < files->next_fd){ + files->next_fd = fd; + } + + spin_unlock(&files->file_lock); + + filp_close(f,files); + + spin_lock(&files->file_lock); + + } + + spin_unlock(&files->file_lock); + + return 0; +} diff --git a/toj/center/src/judgk_proc.h b/toj/center/src/judgk_proc.h new file mode 100755 index 0000000..fd60d30 --- /dev/null +++ b/toj/center/src/judgk_proc.h @@ -0,0 +1,18 @@ +#define PROC_TASK_HTSIZE 1009 + +static int proc_watcher(void *data); +static int proc_get_path(char *in_path,char *real_path); +static int proc_close_fd(struct task_struct *task); + +static struct task_struct *proc_watcher_task; +static LIST_HEAD(proc_task_list); +static struct hlist_head *proc_task_ht; +static DEFINE_SPINLOCK(proc_task_htlock); +static struct kmem_cache *proc_info_cachep; + +int judgk_proc_init(void); +int judgk_proc_exit(void); +int judgk_proc_add(unsigned long arg); +int judgk_proc_get(unsigned long arg); +int judgk_proc_del(unsigned long arg); +struct judgk_proc_info* judgk_proc_task_lookup(struct task_struct *task); diff --git a/toj/center/src/judgk_security.c b/toj/center/src/judgk_security.c new file mode 100755 index 0000000..876bb1b --- /dev/null +++ b/toj/center/src/judgk_security.c @@ -0,0 +1,2698 @@ +#include +#include +#include +#include +#include + +#include"judge_def.h" +#include"judgk.h" +#include"judgk_security.h" + +int judgk_security_hook(){ + + security_hook_addr = security_get_addr(); + + ori_sops = (struct security_operations*)*security_hook_addr; + memcpy(&hook_sops,ori_sops,sizeof(struct security_operations)); + + hook_sops.ptrace_access_check = hook_ptrace_access_check; + hook_sops.ptrace_traceme = hook_ptrace_traceme; + hook_sops.capget = hook_capget; + hook_sops.capset = hook_capset; + //hook_sops.capable = hook_capable; + hook_sops.quotactl = hook_quotactl; + hook_sops.quota_on = hook_quota_on; + hook_sops.syslog = hook_syslog; + hook_sops.settime = hook_settime; + hook_sops.vm_enough_memory = hook_vm_enough_memory; + //hook_sops.bprm_set_creds = hook_bprm_set_creds; + //hook_sops.bprm_check_security = hook_bprm_check_security; + //hook_sops.bprm_secureexec = hook_bprm_secureexec; + //hook_sops.bprm_committing_creds = hook_bprm_committing_creds; + //hook_sops.bprm_committed_creds = hook_bprm_committed_creds; + hook_sops.sb_alloc_security = hook_sb_alloc_security; + hook_sops.sb_free_security = hook_sb_free_security; + hook_sops.sb_copy_data = hook_sb_copy_data; + hook_sops.sb_remount = hook_sb_remount; + hook_sops.sb_kern_mount = hook_sb_kern_mount; + hook_sops.sb_show_options = hook_sb_show_options; + hook_sops.sb_statfs = hook_sb_statfs; + hook_sops.sb_mount = hook_sb_mount; + hook_sops.sb_umount = hook_sb_umount; + hook_sops.sb_pivotroot = hook_sb_pivotroot; + hook_sops.sb_set_mnt_opts = hook_sb_set_mnt_opts; + hook_sops.sb_clone_mnt_opts = hook_sb_clone_mnt_opts; + hook_sops.sb_parse_opts_str = hook_sb_parse_opts_str; + hook_sops.path_unlink = hook_path_unlink; + hook_sops.path_mkdir = hook_path_mkdir; + hook_sops.path_rmdir = hook_path_rmdir; + hook_sops.path_mknod = hook_path_mknod; + hook_sops.path_truncate = hook_path_truncate; + hook_sops.path_symlink = hook_path_symlink; + hook_sops.path_link = hook_path_link; + hook_sops.path_rename = hook_path_rename; + hook_sops.path_chmod = hook_path_chmod; + hook_sops.path_chown = hook_path_chown; + hook_sops.path_chroot = hook_path_chroot; + //hook_sops.inode_alloc_security = hook_inode_alloc_security; + //hook_sops.inode_free_security = hook_inode_free_security; + hook_sops.inode_init_security = hook_inode_init_security; + hook_sops.inode_create = hook_inode_create; + hook_sops.inode_link = hook_inode_link; + hook_sops.inode_unlink = hook_inode_unlink; + hook_sops.inode_symlink = hook_inode_symlink; + hook_sops.inode_mkdir = hook_inode_mkdir; + hook_sops.inode_rmdir = hook_inode_rmdir; + hook_sops.inode_mknod = hook_inode_mknod; + hook_sops.inode_rename = hook_inode_rename; + hook_sops.inode_readlink = hook_inode_readlink; + //hook_sops.inode_follow_link = hook_inode_follow_link; + hook_sops.inode_permission = hook_inode_permission; + hook_sops.inode_setattr = hook_inode_setattr; + //hook_sops.inode_getattr = hook_inode_getattr; + hook_sops.inode_setxattr = hook_inode_setxattr; + hook_sops.inode_post_setxattr = hook_inode_post_setxattr; + hook_sops.inode_getxattr = hook_inode_getxattr; + hook_sops.inode_listxattr = hook_inode_listxattr; + hook_sops.inode_removexattr = hook_inode_removexattr; + hook_sops.inode_need_killpriv = hook_inode_need_killpriv; + hook_sops.inode_killpriv = hook_inode_killpriv; + hook_sops.inode_getsecurity = hook_inode_getsecurity; + hook_sops.inode_setsecurity = hook_inode_setsecurity; + hook_sops.inode_listsecurity = hook_inode_listsecurity; + hook_sops.inode_getsecid = hook_inode_getsecid; + hook_sops.file_permission = hook_file_permission; + //hook_sops.file_alloc_security = hook_file_alloc_security; + //hook_sops.file_free_security = hook_file_free_security; + hook_sops.file_ioctl = hook_file_ioctl; + //hook_sops.mmap_addr = hook_mmap_addr; + //hook_sops.mmap_file = hook_mmap_file; + //hook_sops.file_mprotect = hook_file_mprotect; + hook_sops.file_lock = hook_file_lock; + hook_sops.file_fcntl = hook_file_fcntl; + hook_sops.file_set_fowner = hook_file_set_fowner; + hook_sops.file_send_sigiotask = hook_file_send_sigiotask; + hook_sops.file_receive = hook_file_receive; + hook_sops.file_open = hook_file_open; + hook_sops.task_create = hook_task_create; + //hook_sops.task_free = hook_task_free; + hook_sops.cred_alloc_blank = hook_cred_alloc_blank; + //hook_sops.cred_free = hook_cred_free; + //hook_sops.cred_prepare = hook_cred_prepare; + hook_sops.cred_transfer = hook_cred_transfer; + hook_sops.kernel_act_as = hook_kernel_act_as; + hook_sops.kernel_create_files_as = hook_kernel_create_files_as; + hook_sops.kernel_module_request = hook_kernel_module_request; + hook_sops.task_fix_setuid = hook_task_fix_setuid; + hook_sops.task_setpgid = hook_task_setpgid; + hook_sops.task_getpgid = hook_task_getpgid; + hook_sops.task_getsid = hook_task_getsid; + hook_sops.task_getsecid = hook_task_getsecid; + hook_sops.task_setnice = hook_task_setnice; + hook_sops.task_setioprio = hook_task_setioprio; + hook_sops.task_getioprio = hook_task_getioprio; + hook_sops.task_setrlimit = hook_task_setrlimit; + hook_sops.task_setscheduler = hook_task_setscheduler; + hook_sops.task_getscheduler = hook_task_getscheduler; + hook_sops.task_movememory = hook_task_movememory; + hook_sops.task_kill = hook_task_kill; + hook_sops.task_wait = hook_task_wait; + hook_sops.task_prctl = hook_task_prctl; + hook_sops.task_to_inode = hook_task_to_inode; + hook_sops.ipc_permission = hook_ipc_permission; + hook_sops.ipc_getsecid = hook_ipc_getsecid; + hook_sops.msg_msg_alloc_security = hook_msg_msg_alloc_security; + hook_sops.msg_msg_free_security = hook_msg_msg_free_security; + hook_sops.msg_queue_alloc_security = hook_msg_queue_alloc_security; + hook_sops.msg_queue_free_security = hook_msg_queue_free_security; + hook_sops.msg_queue_associate = hook_msg_queue_associate; + hook_sops.msg_queue_msgctl = hook_msg_queue_msgctl; + hook_sops.msg_queue_msgsnd = hook_msg_queue_msgsnd; + hook_sops.msg_queue_msgrcv = hook_msg_queue_msgrcv; + hook_sops.shm_alloc_security = hook_shm_alloc_security; + hook_sops.shm_free_security = hook_shm_free_security; + hook_sops.shm_associate = hook_shm_associate; + hook_sops.shm_shmctl = hook_shm_shmctl; + hook_sops.shm_shmat = hook_shm_shmat; + hook_sops.sem_alloc_security = hook_sem_alloc_security; + hook_sops.sem_free_security = hook_sem_free_security; + hook_sops.sem_associate = hook_sem_associate; + hook_sops.sem_semctl = hook_sem_semctl; + hook_sops.sem_semop = hook_sem_semop; + hook_sops.netlink_send = hook_netlink_send; + hook_sops.d_instantiate = hook_d_instantiate; + hook_sops.getprocattr = hook_getprocattr; + hook_sops.setprocattr = hook_setprocattr; + hook_sops.secid_to_secctx = hook_secid_to_secctx; + hook_sops.secctx_to_secid = hook_secctx_to_secid; + hook_sops.release_secctx = hook_release_secctx; + hook_sops.inode_notifysecctx = hook_inode_notifysecctx; + hook_sops.inode_setsecctx = hook_inode_setsecctx; + hook_sops.inode_getsecctx = hook_inode_getsecctx; + hook_sops.unix_stream_connect = hook_unix_stream_connect; + hook_sops.unix_may_send = hook_unix_may_send; + hook_sops.socket_create = hook_socket_create; + hook_sops.socket_post_create = hook_socket_post_create; + hook_sops.socket_bind = hook_socket_bind; + hook_sops.socket_connect = hook_socket_connect; + hook_sops.socket_listen = hook_socket_listen; + hook_sops.socket_accept = hook_socket_accept; + hook_sops.socket_sendmsg = hook_socket_sendmsg; + hook_sops.socket_recvmsg = hook_socket_recvmsg; + hook_sops.socket_getsockname = hook_socket_getsockname; + hook_sops.socket_getpeername = hook_socket_getpeername; + hook_sops.socket_getsockopt = hook_socket_getsockopt; + hook_sops.socket_setsockopt = hook_socket_setsockopt; + hook_sops.socket_shutdown = hook_socket_shutdown; + hook_sops.socket_sock_rcv_skb = hook_socket_sock_rcv_skb; + hook_sops.socket_getpeersec_stream = hook_socket_getpeersec_stream; + hook_sops.socket_getpeersec_dgram = hook_socket_getpeersec_dgram; + hook_sops.sk_alloc_security = hook_sk_alloc_security; + hook_sops.sk_free_security = hook_sk_free_security; + hook_sops.sk_clone_security = hook_sk_clone_security; + hook_sops.sk_getsecid = hook_sk_getsecid; + hook_sops.sock_graft = hook_sock_graft; + hook_sops.inet_conn_request = hook_inet_conn_request; + hook_sops.inet_csk_clone = hook_inet_csk_clone; + hook_sops.inet_conn_established = hook_inet_conn_established; + hook_sops.secmark_relabel_packet = hook_secmark_relabel_packet; + hook_sops.secmark_refcount_inc = hook_secmark_refcount_inc; + hook_sops.secmark_refcount_dec = hook_secmark_refcount_dec; + hook_sops.req_classify_flow = hook_req_classify_flow; + hook_sops.tun_dev_create = hook_tun_dev_create; + hook_sops.tun_dev_post_create = hook_tun_dev_post_create; + hook_sops.tun_dev_attach = hook_tun_dev_attach; + hook_sops.key_alloc = hook_key_alloc; + hook_sops.key_free = hook_key_free; + hook_sops.key_permission = hook_key_permission; + hook_sops.key_getsecurity = hook_key_getsecurity; + hook_sops.audit_rule_init = hook_audit_rule_init; + hook_sops.audit_rule_known = hook_audit_rule_known; + hook_sops.audit_rule_match = hook_audit_rule_match; + hook_sops.audit_rule_free = hook_audit_rule_free; + + *security_hook_addr = (unsigned long)&hook_sops; + + return 0; +} +int judgk_security_unhook(){ + *security_hook_addr = (unsigned long)ori_sops; + return 0; +} + +static unsigned long* security_get_addr(){ + ssize_t ret; + int i; + int j; + + struct file *f; + char line[128]; + unsigned char code[3] = {0x48,0xc7,0x05}; + unsigned long addr; + + f = filp_open("/proc/kallsyms",O_RDONLY,0); + set_fs(KERNEL_DS); + + i = 0; + addr = 0; + while(true){ + ret = f->f_op->read(f,&line[i],1,&f->f_pos); + + if(line[i] == '\n' || ret <= 0){ + line[i] = '\0'; + + addr = 0; + for(j = 0;j < i;j++){ + if(line[j] == ' '){ + j++; + break; + } + + addr *= 16UL; + if(line[j] >= '0' && line[j] <= '9'){ + addr += (unsigned long)(line[j] - '0'); + }else{ + addr += (unsigned long)(line[j] - 'a' + 10); + } + } + for(;j < i;j++){ + if(line[j] == ' '){ + j++; + break; + } + } + if(j < i){ + if(strcmp("reset_security_ops",line + j) == 0){ + break; + } + } + + i = 0; + }else{ + i++; + } + + if(ret <= 0){ + break; + } + } + + set_fs(USER_DS); + filp_close(f,NULL); + + i = 0; + while(i < 3){ + if(*(unsigned char*)addr != code[i]){ + i = 0; + }else{ + i++; + } + addr++; + } + + return (unsigned long*)(addr + (unsigned long)*(unsigned int*)addr + 8UL); +} +static inline void security_hook_rf(struct judgk_proc_info *info){ + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); +} + +static int hook_inode_permission(struct inode *inode,int mask){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inode_permission(inode,mask); + } + + if((mask & ~(MAY_EXEC | MAY_READ | MAY_OPEN | MAY_CHDIR | MAY_NOT_BLOCK)) != 0){ + pr_alert("judgk:PID %d RF inode_permission %08x\n",current->tgid,mask); + + security_hook_rf(info); + return -EACCES; + } + return ori_sops->inode_permission(inode,mask); +} +static int hook_file_permission(struct file *file,int mask){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->file_permission(file,mask); + } + + if((mask & ~(MAY_READ | MAY_WRITE)) != 0){ + security_hook_rf(info); + return -EACCES; + }else if((mask & MAY_WRITE) != 0 && file != info->std_out){ + security_hook_rf(info); + return -EACCES; + } + return ori_sops->file_permission(file,mask); +} +static int hook_file_open(struct file *file, const struct cred *cred){ + int ret; + int i; + + struct judgk_proc_info *info; + char *buf_path,*path; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->file_open(file,cred); + } + + ret = 0; + buf_path = kmalloc(sizeof(char) * (PATH_MAX + 1),GFP_KERNEL); + path = d_path(&file->f_path,buf_path,PATH_MAX + 1); + + if((file->f_mode & !(FMODE_READ | FMODE_LSEEK | FMODE_PREAD | FMODE_EXEC)) != 0){ + ret = -EACCES; + }else if(strcmp(path,"/proc/meminfo") != 0){ + i = 0; + while(info->run_path[i] != '\0'){ + if(path[i] != info->run_path[i]){ + ret = -EACCES; + break; + } + i++; + } + if(path[i] == info->run_path[i]){ + ret = -EACCES; + } + } + + kfree(buf_path); + + if(ret != 0){ + pr_alert("judgk:PID %d RF file_open %s %08x\n",current->tgid,path,file->f_mode); + + security_hook_rf(info); + return ret; + } + return ori_sops->file_open(file,cred); +} +static int hook_file_ioctl(struct file *file,unsigned int cmd,unsigned long arg){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->file_ioctl(file,cmd,arg); + } + + if(file != info->std_in && file != info->std_out){ + pr_alert("judgk:PID %d file_ioctl\n",current->tgid); + + security_hook_rf(info); + return -EACCES; + } + return ori_sops->file_ioctl(file,cmd,arg); +} +static int hook_vm_enough_memory(struct mm_struct *mm,long pages){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL)){ + return ori_sops->vm_enough_memory(mm,pages); + } + + info->memory = (mm->total_vm + pages) << PAGE_SHIFT; + //pr_alert("judgk:PID %d vm_enough_memory %lu\n",current->tgid,info->memory); + + if(info->memory > info->memlimit){ + info->status = JUDGE_MLE; + send_sig(SIGKILL,current,0); + return -EACCES; + } + return ori_sops->vm_enough_memory(mm,pages); +} + + + + +static int hook_ptrace_access_check(struct task_struct *child,unsigned int mode){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->ptrace_access_check(child,mode); + } + + pr_alert("judgk:PID %d ptrace_access_check\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_ptrace_traceme(struct task_struct *parent){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->ptrace_traceme(parent); + } + + pr_alert("judgk:PID %d ptrace_traceme\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_capget(struct task_struct *target,kernel_cap_t *effective,kernel_cap_t *inheritable,kernel_cap_t *permitted){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->capget(target,effective,inheritable,permitted); + } + + pr_alert("judgk:PID %d capget\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_capset(struct cred *new,const struct cred *old,const kernel_cap_t *effective,const kernel_cap_t *inheritable,const kernel_cap_t *permitted){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->capset(new,old,effective,inheritable,permitted); + } + + pr_alert("judgk:PID %d capset\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +/*static int hook_capable(const struct cred *cred,struct user_namespace *ns,int cap,int audit){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->capable(cred,ns,cap,audit); + } + + pr_alert("judgk:PID %d capable\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +}*/ +static int hook_quotactl(int cmds,int type,int id,struct super_block *sb){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->quotactl(cmds,type,id,sb); + } + + pr_alert("judgk:PID %d quotactl\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_quota_on(struct dentry *dentry){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->quota_on(dentry); + } + + pr_alert("judgk:PID %d quota_on\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_syslog(int type){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->syslog(type); + } + + pr_alert("judgk:PID %d syslog\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_settime(const struct timespec *ts,const struct timezone *tz){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->settime(ts,tz); + } + + pr_alert("judgk:PID %d settime\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +/*static int hook_bprm_set_creds(struct linux_binprm *bprm){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->bprm_set_creds(bprm); + } + + pr_alert("judgk:PID %d bprm_set_creds\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_bprm_check_security(struct linux_binprm *bprm){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->bprm_check_security(bprm); + } + + pr_alert("judgk:PID %d bprm_check_security\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_bprm_secureexec(struct linux_binprm *bprm){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->bprm_secureexec(bprm); + } + + pr_alert("judgk:PID %d bprm_secureexec\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static void hook_bprm_committing_creds(struct linux_binprm *bprm){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->bprm_committing_creds(bprm); + } + + pr_alert("judgk:PID %d bprm_committing_creds\n",current->tgid); + + security_hook_rf(info); +} +static void hook_bprm_committed_creds(struct linux_binprm *bprm){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->bprm_committed_creds(bprm); + } + + pr_alert("judgk:PID %d bprm_committed_creds\n",current->tgid); + + security_hook_rf(info); +}*/ +static int hook_sb_alloc_security(struct super_block *sb){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->sb_alloc_security(sb); + } + + pr_alert("judgk:PID %d sb_alloc_security\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static void hook_sb_free_security(struct super_block *sb){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->sb_free_security(sb); + } + + pr_alert("judgk:PID %d sb_free_security\n",current->tgid); + + security_hook_rf(info); +} +static int hook_sb_copy_data(char *orig,char *copy){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->sb_copy_data(orig,copy); + } + + pr_alert("judgk:PID %d sb_copy_data\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_sb_remount(struct super_block *sb,void *data){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->sb_remount(sb,data); + } + + pr_alert("judgk:PID %d sb_remount\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_sb_kern_mount(struct super_block *sb,int flags,void *data){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->sb_kern_mount(sb,flags,data); + } + + pr_alert("judgk:PID %d sb_kern_mount\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_sb_show_options(struct seq_file *m,struct super_block *sb){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->sb_show_options(m,sb); + } + + pr_alert("judgk:PID %d sb_show_options\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_sb_statfs(struct dentry *dentry){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->sb_statfs(dentry); + } + + pr_alert("judgk:PID %d sb_statfs\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_sb_mount(const char *dev_name,struct path *path,const char *type,unsigned long flags,void *data){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->sb_mount(dev_name,path,type,flags,data); + } + + pr_alert("judgk:PID %d sb_mount\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_sb_umount(struct vfsmount *mnt,int flags){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->sb_umount(mnt,flags); + } + + pr_alert("judgk:PID %d sb_umount\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_sb_pivotroot(struct path *old_path,struct path *new_path){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->sb_pivotroot(old_path,new_path); + } + + pr_alert("judgk:PID %d sb_pivotroot\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_sb_set_mnt_opts(struct super_block *sb,struct security_mnt_opts *opts){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->sb_set_mnt_opts(sb,opts); + } + + pr_alert("judgk:PID %d sb_set_mnt_opts\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static void hook_sb_clone_mnt_opts(const struct super_block *oldsb,struct super_block *newsb){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->sb_clone_mnt_opts(oldsb,newsb); + } + + pr_alert("judgk:PID %d sb_clone_mnt_opts\n",current->tgid); + + security_hook_rf(info); +} +static int hook_sb_parse_opts_str(char *options,struct security_mnt_opts *opts){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->sb_parse_opts_str(options,opts); + } + + pr_alert("judgk:PID %d sb_parse_opts_str\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_path_unlink(struct path *dir,struct dentry *dentry){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->path_unlink(dir,dentry); + } + + pr_alert("judgk:PID %d path_unlink\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_path_mkdir(struct path *dir,struct dentry *dentry,umode_t mode){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->path_mkdir(dir,dentry,mode); + } + + pr_alert("judgk:PID %d path_mkdir\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_path_rmdir(struct path *dir,struct dentry *dentry){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->path_rmdir(dir,dentry); + } + + pr_alert("judgk:PID %d path_rmdir\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_path_mknod(struct path *dir,struct dentry *dentry,umode_t mode,unsigned int dev){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->path_mknod(dir,dentry,mode,dev); + } + + pr_alert("judgk:PID %d path_mknod\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_path_truncate(struct path *path){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->path_truncate(path); + } + + pr_alert("judgk:PID %d path_truncate\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_path_symlink(struct path *dir,struct dentry *dentry,const char *old_name){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->path_symlink(dir,dentry,old_name); + } + + pr_alert("judgk:PID %d path_symlink\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_path_link(struct dentry *old_dentry,struct path *new_dir,struct dentry *new_dentry){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->path_link(old_dentry,new_dir,new_dentry); + } + + pr_alert("judgk:PID %d path_link\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_path_rename(struct path *old_dir,struct dentry *old_dentry,struct path *new_dir,struct dentry *new_dentry){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->path_rename(old_dir,old_dentry,new_dir,new_dentry); + } + + pr_alert("judgk:PID %d path_rename\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_path_chmod(struct path *path,umode_t mode){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->path_chmod(path,mode); + } + + pr_alert("judgk:PID %d path_chmod\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_path_chown(struct path *path,kuid_t uid,kgid_t gid){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->path_chown(path,uid,gid); + } + + pr_alert("judgk:PID %d path_chown\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_path_chroot(struct path *path){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->path_chroot(path); + } + + pr_alert("judgk:PID %d path_chroot\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +/*static int hook_inode_alloc_security(struct inode *inode){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inode_alloc_security(inode); + } + + pr_alert("judgk:PID %d inode_alloc_security\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static void hook_inode_free_security(struct inode *inode){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inode_free_security(inode); + } + + pr_alert("judgk:PID %d inode_free_security\n",current->tgid); + + security_hook_rf(info); +}*/ +static int hook_inode_init_security(struct inode *inode,struct inode *dir,const struct qstr *qstr,char **name,void **value,size_t *len){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inode_init_security(inode,dir,qstr,name,value,len); + } + + pr_alert("judgk:PID %d inode_init_security\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_inode_create(struct inode *dir,struct dentry *dentry,umode_t mode){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inode_create(dir,dentry,mode); + } + + pr_alert("judgk:PID %d inode_create\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_inode_link(struct dentry *old_dentry,struct inode *dir,struct dentry *new_dentry){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inode_link(old_dentry,dir,new_dentry); + } + + pr_alert("judgk:PID %d inode_link\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_inode_unlink(struct inode *dir,struct dentry *dentry){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inode_unlink(dir,dentry); + } + + pr_alert("judgk:PID %d inode_unlink\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_inode_symlink(struct inode *dir,struct dentry *dentry,const char *old_name){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inode_symlink(dir,dentry,old_name); + } + + pr_alert("judgk:PID %d inode_symlink\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_inode_mkdir(struct inode *dir,struct dentry *dentry,umode_t mode){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inode_mkdir(dir,dentry,mode); + } + + pr_alert("judgk:PID %d inode_mkdir\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_inode_rmdir(struct inode *dir,struct dentry *dentry){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inode_rmdir(dir,dentry); + } + + pr_alert("judgk:PID %d inode_rmdir\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_inode_mknod(struct inode *dir,struct dentry *dentry,umode_t mode,dev_t dev){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inode_mknod(dir,dentry,mode,dev); + } + + pr_alert("judgk:PID %d inode_mknod\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_inode_rename(struct inode *old_dir,struct dentry *old_dentry,struct inode *new_dir,struct dentry *new_dentry){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inode_rename(old_dir,old_dentry,new_dir,new_dentry); + } + + pr_alert("judgk:PID %d inode_rename\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_inode_readlink(struct dentry *dentry){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inode_readlink(dentry); + } + + pr_alert("judgk:PID %d inode_readlink\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +/*static int hook_inode_follow_link(struct dentry *dentry,struct nameidata *nd){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inode_follow_link(dentry,nd); + } + + pr_alert("judgk:PID %d inode_follow_link\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +}*/ +static int hook_inode_setattr(struct dentry *dentry,struct iattr *attr){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inode_setattr(dentry,attr); + } + + pr_alert("judgk:PID %d inode_setattr\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +/*static int hook_inode_getattr(struct vfsmount *mnt,struct dentry *dentry){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inode_getattr(mnt,dentry); + } + + pr_alert("judgk:PID %d inode_getattr\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +}*/ +static int hook_inode_setxattr(struct dentry *dentry,const char *name,const void *value,size_t size,int flags){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inode_setxattr(dentry,name,value,size,flags); + } + + pr_alert("judgk:PID %d inode_setxattr\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static void hook_inode_post_setxattr(struct dentry *dentry,const char *name,const void *value,size_t size,int flags){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inode_post_setxattr(dentry,name,value,size,flags); + } + + pr_alert("judgk:PID %d inode_post_setxattr\n",current->tgid); + + security_hook_rf(info); +} +static int hook_inode_getxattr(struct dentry *dentry,const char *name){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inode_getxattr(dentry,name); + } + + pr_alert("judgk:PID %d inode_getxattr\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_inode_listxattr(struct dentry *dentry){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inode_listxattr(dentry); + } + + pr_alert("judgk:PID %d inode_listxattr\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_inode_removexattr(struct dentry *dentry,const char *name){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inode_removexattr(dentry,name); + } + + pr_alert("judgk:PID %d inode_removexattr\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_inode_need_killpriv(struct dentry *dentry){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inode_need_killpriv(dentry); + } + + pr_alert("judgk:PID %d inode_need_killpriv\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_inode_killpriv(struct dentry *dentry){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inode_killpriv(dentry); + } + + pr_alert("judgk:PID %d inode_killpriv\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_inode_getsecurity(const struct inode *inode,const char *name,void **buffer,bool alloc){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inode_getsecurity(inode,name,buffer,alloc); + } + + pr_alert("judgk:PID %d inode_getsecurity\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_inode_setsecurity(struct inode *inode,const char *name,const void *value,size_t size,int flags){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inode_setsecurity(inode,name,value,size,flags); + } + + pr_alert("judgk:PID %d inode_setsecurity\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_inode_listsecurity(struct inode *inode,char *buffer,size_t buffer_size){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inode_listsecurity(inode,buffer,buffer_size); + } + + pr_alert("judgk:PID %d inode_listsecurity\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static void hook_inode_getsecid(const struct inode *inode,u32 *secid){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inode_getsecid(inode,secid); + } + + pr_alert("judgk:PID %d inode_getsecid\n",current->tgid); + + security_hook_rf(info); +} +/*static int hook_file_alloc_security(struct file *file){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->file_alloc_security(file); + } + + pr_alert("judgk:PID %d file_alloc_security\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static void hook_file_free_security(struct file *file){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->file_free_security(file); + } + + pr_alert("judgk:PID %d file_free_security\n",current->tgid); + + security_hook_rf(info); +} +static int hook_mmap_addr(unsigned long addr){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->mmap_addr(addr); + } + + pr_alert("judgk:PID %d mmap_addr\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_mmap_file(struct file *file,unsigned long reqprot,unsigned long prot,unsigned long flags){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->mmap_file(file,reqprot,prot,flags); + } + + pr_alert("judgk:PID %d mmap_file\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_file_mprotect(struct vm_area_struct *vma,unsigned long reqprot,unsigned long prot){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->file_mprotect(vma,reqprot,prot); + } + + pr_alert("judgk:PID %d file_mprotect\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +}*/ +static int hook_file_lock(struct file *file,unsigned int cmd){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->file_lock(file,cmd); + } + + pr_alert("judgk:PID %d file_lock\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_file_fcntl(struct file *file,unsigned int cmd,unsigned long arg){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->file_fcntl(file,cmd,arg); + } + + pr_alert("judgk:PID %d file_fcntl\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_file_set_fowner(struct file *file){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->file_set_fowner(file); + } + + pr_alert("judgk:PID %d file_set_fowner\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_file_send_sigiotask(struct task_struct *tsk,struct fown_struct *fown,int sig){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->file_send_sigiotask(tsk,fown,sig); + } + + pr_alert("judgk:PID %d file_send_sigiotask\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_file_receive(struct file *file){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->file_receive(file); + } + + pr_alert("judgk:PID %d file_receive\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_task_create(unsigned long clone_flags){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->task_create(clone_flags); + } + + pr_alert("judgk:PID %d task_create\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +/*static void hook_task_free(struct task_struct *task){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->task_free(task); + } + + pr_alert("judgk:PID %d task_free\n",current->tgid); + + security_hook_rf(info); +}*/ +static int hook_cred_alloc_blank(struct cred *cred,gfp_t gfp){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->cred_alloc_blank(cred,gfp); + } + + pr_alert("judgk:PID %d cred_alloc_blank\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +/*static void hook_cred_free(struct cred *cred){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->cred_free(cred); + } + + pr_alert("judgk:PID %d cred_free\n",current->tgid); + + security_hook_rf(info); +} +static int hook_cred_prepare(struct cred *new,const struct cred *old,gfp_t gfp){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->cred_prepare(new,old,gfp); + } + + pr_alert("judgk:PID %d cred_prepare\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +}*/ +static void hook_cred_transfer(struct cred *new,const struct cred *old){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->cred_transfer(new,old); + } + + pr_alert("judgk:PID %d cred_transfer\n",current->tgid); + + security_hook_rf(info); +} +static int hook_kernel_act_as(struct cred *new,u32 secid){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->kernel_act_as(new,secid); + } + + pr_alert("judgk:PID %d kernel_act_as\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_kernel_create_files_as(struct cred *new,struct inode *inode){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->kernel_create_files_as(new,inode); + } + + pr_alert("judgk:PID %d kernel_create_files_as\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_kernel_module_request(char *kmod_name){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->kernel_module_request(kmod_name); + } + + pr_alert("judgk:PID %d kernel_module_request\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_task_fix_setuid(struct cred *new,const struct cred *old,int flags){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->task_fix_setuid(new,old,flags); + } + + pr_alert("judgk:PID %d task_fix_setuid\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_task_setpgid(struct task_struct *p,pid_t pgid){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->task_setpgid(p,pgid); + } + + pr_alert("judgk:PID %d task_setpgid\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_task_getpgid(struct task_struct *p){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->task_getpgid(p); + } + + pr_alert("judgk:PID %d task_getpgid\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_task_getsid(struct task_struct *p){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->task_getsid(p); + } + + pr_alert("judgk:PID %d task_getsid\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static void hook_task_getsecid(struct task_struct *p,u32 *secid){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->task_getsecid(p,secid); + } + + pr_alert("judgk:PID %d task_getsecid\n",current->tgid); + + security_hook_rf(info); +} +static int hook_task_setnice(struct task_struct *p,int nice){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->task_setnice(p,nice); + } + + pr_alert("judgk:PID %d task_setnice\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_task_setioprio(struct task_struct *p,int ioprio){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->task_setioprio(p,ioprio); + } + + pr_alert("judgk:PID %d task_setioprio\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_task_getioprio(struct task_struct *p){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->task_getioprio(p); + } + + pr_alert("judgk:PID %d task_getioprio\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_task_setrlimit(struct task_struct *p,unsigned int resource,struct rlimit *new_rlim){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->task_setrlimit(p,resource,new_rlim); + } + + pr_alert("judgk:PID %d task_setrlimit\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_task_setscheduler(struct task_struct *p){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->task_setscheduler(p); + } + + pr_alert("judgk:PID %d task_setscheduler\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_task_getscheduler(struct task_struct *p){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->task_getscheduler(p); + } + + pr_alert("judgk:PID %d task_getscheduler\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_task_movememory(struct task_struct *p){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->task_movememory(p); + } + + pr_alert("judgk:PID %d task_movememory\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_task_kill(struct task_struct *p,struct siginfo *siginfo,int sig,u32 secid){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->task_kill(p,siginfo,sig,secid); + } + + pr_alert("judgk:PID %d task_kill\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_task_wait(struct task_struct *p){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->task_wait(p); + } + + pr_alert("judgk:PID %d task_wait\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_task_prctl(int option,unsigned long arg2,unsigned long arg3,unsigned long arg4,unsigned long arg5){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->task_prctl(option,arg2,arg3,arg4,arg5); + } + + pr_alert("judgk:PID %d task_prctl\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static void hook_task_to_inode(struct task_struct *p,struct inode *inode){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->task_to_inode(p,inode); + } + + pr_alert("judgk:PID %d task_to_inode\n",current->tgid); + + security_hook_rf(info); +} +static int hook_ipc_permission(struct kern_ipc_perm *ipcp,short flag){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->ipc_permission(ipcp,flag); + } + + pr_alert("judgk:PID %d ipc_permission\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static void hook_ipc_getsecid(struct kern_ipc_perm *ipcp,u32 *secid){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->ipc_getsecid(ipcp,secid); + } + + pr_alert("judgk:PID %d ipc_getsecid\n",current->tgid); + + security_hook_rf(info); +} +static int hook_msg_msg_alloc_security(struct msg_msg *msg){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->msg_msg_alloc_security(msg); + } + + pr_alert("judgk:PID %d msg_msg_alloc_security\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static void hook_msg_msg_free_security(struct msg_msg *msg){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->msg_msg_free_security(msg); + } + + pr_alert("judgk:PID %d msg_msg_free_security\n",current->tgid); + + security_hook_rf(info); +} +static int hook_msg_queue_alloc_security(struct msg_queue *msq){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->msg_queue_alloc_security(msq); + } + + pr_alert("judgk:PID %d msg_queue_alloc_security\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static void hook_msg_queue_free_security(struct msg_queue *msq){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->msg_queue_free_security(msq); + } + + pr_alert("judgk:PID %d msg_queue_free_security\n",current->tgid); + + security_hook_rf(info); +} +static int hook_msg_queue_associate(struct msg_queue *msq,int msqflg){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->msg_queue_associate(msq,msqflg); + } + + pr_alert("judgk:PID %d msg_queue_associate\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_msg_queue_msgctl(struct msg_queue *msq,int cmd){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->msg_queue_msgctl(msq,cmd); + } + + pr_alert("judgk:PID %d msg_queue_msgctl\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_msg_queue_msgsnd(struct msg_queue *msq,struct msg_msg *msg,int msqflg){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->msg_queue_msgsnd(msq,msg,msqflg); + } + + pr_alert("judgk:PID %d msg_queue_msgsnd\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_msg_queue_msgrcv(struct msg_queue *msq,struct msg_msg *msg,struct task_struct *target,long type,int mode){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->msg_queue_msgrcv(msq,msg,target,type,mode); + } + + pr_alert("judgk:PID %d msg_queue_msgrcv\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_shm_alloc_security(struct shmid_kernel *shp){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->shm_alloc_security(shp); + } + + pr_alert("judgk:PID %d shm_alloc_security\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static void hook_shm_free_security(struct shmid_kernel *shp){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->shm_free_security(shp); + } + + pr_alert("judgk:PID %d shm_free_security\n",current->tgid); + + security_hook_rf(info); +} +static int hook_shm_associate(struct shmid_kernel *shp,int shmflg){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->shm_associate(shp,shmflg); + } + + pr_alert("judgk:PID %d shm_associate\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_shm_shmctl(struct shmid_kernel *shp,int cmd){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->shm_shmctl(shp,cmd); + } + + pr_alert("judgk:PID %d shm_shmctl\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_shm_shmat(struct shmid_kernel *shp,char __user *shmaddr,int shmflg){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->shm_shmat(shp,shmaddr,shmflg); + } + + pr_alert("judgk:PID %d shm_shmat\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_sem_alloc_security(struct sem_array *sma){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->sem_alloc_security(sma); + } + + pr_alert("judgk:PID %d sem_alloc_security\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static void hook_sem_free_security(struct sem_array *sma){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->sem_free_security(sma); + } + + pr_alert("judgk:PID %d sem_free_security\n",current->tgid); + + security_hook_rf(info); +} +static int hook_sem_associate(struct sem_array *sma,int semflg){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->sem_associate(sma,semflg); + } + + pr_alert("judgk:PID %d sem_associate\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_sem_semctl(struct sem_array *sma,int cmd){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->sem_semctl(sma,cmd); + } + + pr_alert("judgk:PID %d sem_semctl\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_sem_semop(struct sem_array *sma,struct sembuf *sops,unsigned nsops,int alter){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->sem_semop(sma,sops,nsops,alter); + } + + pr_alert("judgk:PID %d sem_semop\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_netlink_send(struct sock *sk,struct sk_buff *skb){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->netlink_send(sk,skb); + } + + pr_alert("judgk:PID %d netlink_send\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static void hook_d_instantiate(struct dentry *dentry,struct inode *inode){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->d_instantiate(dentry,inode); + } + + pr_alert("judgk:PID %d d_instantiate\n",current->tgid); + + security_hook_rf(info); +} +static int hook_getprocattr(struct task_struct *p,char *name,char **value){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->getprocattr(p,name,value); + } + + pr_alert("judgk:PID %d getprocattr\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_setprocattr(struct task_struct *p,char *name,void *value,size_t size){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->setprocattr(p,name,value,size); + } + + pr_alert("judgk:PID %d setprocattr\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_secid_to_secctx(u32 secid,char **secdata,u32 *seclen){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->secid_to_secctx(secid,secdata,seclen); + } + + pr_alert("judgk:PID %d secid_to_secctx\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_secctx_to_secid(const char *secdata,u32 seclen,u32 *secid){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->secctx_to_secid(secdata,seclen,secid); + } + + pr_alert("judgk:PID %d secctx_to_secid\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static void hook_release_secctx(char *secdata,u32 seclen){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->release_secctx(secdata,seclen); + } + + pr_alert("judgk:PID %d release_secctx\n",current->tgid); + + security_hook_rf(info); +} +static int hook_inode_notifysecctx(struct inode *inode,void *ctx,u32 ctxlen){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inode_notifysecctx(inode,ctx,ctxlen); + } + + pr_alert("judgk:PID %d inode_notifysecctx\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_inode_setsecctx(struct dentry *dentry,void *ctx,u32 ctxlen){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inode_setsecctx(dentry,ctx,ctxlen); + } + + pr_alert("judgk:PID %d inode_setsecctx\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_inode_getsecctx(struct inode *inode,void **ctx,u32 *ctxlen){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inode_getsecctx(inode,ctx,ctxlen); + } + + pr_alert("judgk:PID %d inode_getsecctx\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_unix_stream_connect(struct sock *sock,struct sock *other,struct sock *newsk){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->unix_stream_connect(sock,other,newsk); + } + + pr_alert("judgk:PID %d unix_stream_connect\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_unix_may_send(struct socket *sock,struct socket *other){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->unix_may_send(sock,other); + } + + pr_alert("judgk:PID %d unix_may_send\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_socket_create(int family,int type,int protocol,int kern){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->socket_create(family,type,protocol,kern); + } + + pr_alert("judgk:PID %d socket_create\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_socket_post_create(struct socket *sock,int family,int type,int protocol,int kern){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->socket_post_create(sock,family,type,protocol,kern); + } + + pr_alert("judgk:PID %d socket_post_create\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_socket_bind(struct socket *sock,struct sockaddr *address,int addrlen){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->socket_bind(sock,address,addrlen); + } + + pr_alert("judgk:PID %d socket_bind\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_socket_connect(struct socket *sock,struct sockaddr *address,int addrlen){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->socket_connect(sock,address,addrlen); + } + + pr_alert("judgk:PID %d socket_connect\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_socket_listen(struct socket *sock,int backlog){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->socket_listen(sock,backlog); + } + + pr_alert("judgk:PID %d socket_listen\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_socket_accept(struct socket *sock,struct socket *newsock){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->socket_accept(sock,newsock); + } + + pr_alert("judgk:PID %d socket_accept\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_socket_sendmsg(struct socket *sock,struct msghdr *msg,int size){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->socket_sendmsg(sock,msg,size); + } + + pr_alert("judgk:PID %d socket_sendmsg\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_socket_recvmsg(struct socket *sock,struct msghdr *msg,int size,int flags){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->socket_recvmsg(sock,msg,size,flags); + } + + pr_alert("judgk:PID %d socket_recvmsg\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_socket_getsockname(struct socket *sock){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->socket_getsockname(sock); + } + + pr_alert("judgk:PID %d socket_getsockname\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_socket_getpeername(struct socket *sock){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->socket_getpeername(sock); + } + + pr_alert("judgk:PID %d socket_getpeername\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_socket_getsockopt(struct socket *sock,int level,int optname){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->socket_getsockopt(sock,level,optname); + } + + pr_alert("judgk:PID %d socket_getsockopt\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_socket_setsockopt(struct socket *sock,int level,int optname){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->socket_setsockopt(sock,level,optname); + } + + pr_alert("judgk:PID %d socket_setsockopt\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_socket_shutdown(struct socket *sock,int how){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->socket_shutdown(sock,how); + } + + pr_alert("judgk:PID %d socket_shutdown\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_socket_sock_rcv_skb(struct sock *sk,struct sk_buff *skb){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->socket_sock_rcv_skb(sk,skb); + } + + pr_alert("judgk:PID %d socket_sock_rcv_skb\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_socket_getpeersec_stream(struct socket *sock,char __user *optval,int __user *optlen,unsigned len){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->socket_getpeersec_stream(sock,optval,optlen,len); + } + + pr_alert("judgk:PID %d socket_getpeersec_stream\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_socket_getpeersec_dgram(struct socket *sock,struct sk_buff *skb,u32 *secid){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->socket_getpeersec_dgram(sock,skb,secid); + } + + pr_alert("judgk:PID %d socket_getpeersec_dgram\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_sk_alloc_security(struct sock *sk,int family,gfp_t priority){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->sk_alloc_security(sk,family,priority); + } + + pr_alert("judgk:PID %d sk_alloc_security\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static void hook_sk_free_security(struct sock *sk){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->sk_free_security(sk); + } + + pr_alert("judgk:PID %d sk_free_security\n",current->tgid); + + security_hook_rf(info); +} +static void hook_sk_clone_security(const struct sock *sk,struct sock *newsk){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->sk_clone_security(sk,newsk); + } + + pr_alert("judgk:PID %d sk_clone_security\n",current->tgid); + + security_hook_rf(info); +} +static void hook_sk_getsecid(struct sock *sk,u32 *secid){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->sk_getsecid(sk,secid); + } + + pr_alert("judgk:PID %d sk_getsecid\n",current->tgid); + + security_hook_rf(info); +} +static void hook_sock_graft(struct sock *sk,struct socket *parent){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->sock_graft(sk,parent); + } + + pr_alert("judgk:PID %d sock_graft\n",current->tgid); + + security_hook_rf(info); +} +static int hook_inet_conn_request(struct sock *sk,struct sk_buff *skb,struct request_sock *req){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inet_conn_request(sk,skb,req); + } + + pr_alert("judgk:PID %d inet_conn_request\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static void hook_inet_csk_clone(struct sock *newsk,const struct request_sock *req){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inet_csk_clone(newsk,req); + } + + pr_alert("judgk:PID %d inet_csk_clone\n",current->tgid); + + security_hook_rf(info); +} +static void hook_inet_conn_established(struct sock *sk,struct sk_buff *skb){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->inet_conn_established(sk,skb); + } + + pr_alert("judgk:PID %d inet_conn_established\n",current->tgid); + + security_hook_rf(info); +} +static int hook_secmark_relabel_packet(u32 secid){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->secmark_relabel_packet(secid); + } + + pr_alert("judgk:PID %d secmark_relabel_packet\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static void hook_secmark_refcount_inc(){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->secmark_refcount_inc(); + } + + pr_alert("judgk:PID %d secmark_refcount_inc\n",current->tgid); + + security_hook_rf(info); +} +static void hook_secmark_refcount_dec(){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->secmark_refcount_dec(); + } + + pr_alert("judgk:PID %d secmark_refcount_dec\n",current->tgid); + + security_hook_rf(info); +} +static void hook_req_classify_flow(const struct request_sock *req,struct flowi *fl){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->req_classify_flow(req,fl); + } + + pr_alert("judgk:PID %d req_classify_flow\n",current->tgid); + + security_hook_rf(info); +} +static int hook_tun_dev_create(){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->tun_dev_create(); + } + + pr_alert("judgk:PID %d tun_dev_create\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static void hook_tun_dev_post_create(struct sock *sk){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->tun_dev_post_create(sk); + } + + pr_alert("judgk:PID %d tun_dev_post_create\n",current->tgid); + + security_hook_rf(info); +} +static int hook_tun_dev_attach(struct sock *sk){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->tun_dev_attach(sk); + } + + pr_alert("judgk:PID %d tun_dev_attach\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +/*static int hook_xfrm_policy_alloc_security(struct xfrm_sec_ctx **ctxp,struct xfrm_user_sec_ctx *sec_ctx){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->xfrm_policy_alloc_security(ctxp,sec_ctx); + } + + pr_alert("judgk:PID %d xfrm_policy_alloc_security\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_xfrm_policy_clone_security(struct xfrm_sec_ctx *old_ctx,struct xfrm_sec_ctx **new_ctx){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->xfrm_policy_clone_security(old_ctx,new_ctx); + } + + pr_alert("judgk:PID %d xfrm_policy_clone_security\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static void hook_xfrm_policy_free_security(struct xfrm_sec_ctx *ctx){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->xfrm_policy_free_security(ctx); + } + + pr_alert("judgk:PID %d xfrm_policy_free_security\n",current->tgid); + + security_hook_rf(info); +} +static int hook_xfrm_policy_delete_security(struct xfrm_sec_ctx *ctx){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->xfrm_policy_delete_security(ctx); + } + + pr_alert("judgk:PID %d xfrm_policy_delete_security\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_xfrm_state_alloc_security(struct xfrm_state *x,struct xfrm_user_sec_ctx *sec_ctx,u32 secid){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->xfrm_state_alloc_security(x,sec_ctx,secid); + } + + pr_alert("judgk:PID %d xfrm_state_alloc_security\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static void hook_xfrm_state_free_security(struct xfrm_state *x){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->xfrm_state_free_security(x); + } + + pr_alert("judgk:PID %d xfrm_state_free_security\n",current->tgid); + + security_hook_rf(info); +} +static int hook_xfrm_state_delete_security(struct xfrm_state *x){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->xfrm_state_delete_security(x); + } + + pr_alert("judgk:PID %d xfrm_state_delete_security\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx,u32 fl_secid,u8 dir){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->xfrm_policy_lookup(ctx,fl_secid,dir); + } + + pr_alert("judgk:PID %d xfrm_policy_lookup\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_xfrm_state_pol_flow_match(struct xfrm_state *x,struct xfrm_policy *xp,const struct flowi *fl){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->xfrm_state_pol_flow_match(x,xp,fl); + } + + pr_alert("judgk:PID %d xfrm_state_pol_flow_match\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_xfrm_decode_session(struct sk_buff *skb,u32 *secid,int ckall){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->xfrm_decode_session(skb,secid,ckall); + } + + pr_alert("judgk:PID %d xfrm_decode_session\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +}*/ +static int hook_key_alloc(struct key *key,const struct cred *cred,unsigned long flags){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->key_alloc(key,cred,flags); + } + + pr_alert("judgk:PID %d key_alloc\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static void hook_key_free(struct key *key){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->key_free(key); + } + + pr_alert("judgk:PID %d key_free\n",current->tgid); + + security_hook_rf(info); +} +static int hook_key_permission(key_ref_t key_ref,const struct cred *cred,key_perm_t perm){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->key_permission(key_ref,cred,perm); + } + + pr_alert("judgk:PID %d key_permission\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_key_getsecurity(struct key *key,char **_buffer){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->key_getsecurity(key,_buffer); + } + + pr_alert("judgk:PID %d key_getsecurity\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_audit_rule_init(u32 field,u32 op,char *rulestr,void **lsmrule){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->audit_rule_init(field,op,rulestr,lsmrule); + } + + pr_alert("judgk:PID %d audit_rule_init\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_audit_rule_known(struct audit_krule *krule){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->audit_rule_known(krule); + } + + pr_alert("judgk:PID %d audit_rule_known\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static int hook_audit_rule_match(u32 secid,u32 field,u32 op,void *lsmrule,struct audit_context *actx){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->audit_rule_match(secid,field,op,lsmrule,actx); + } + + pr_alert("judgk:PID %d audit_rule_match\n",current->tgid); + + security_hook_rf(info); + return -EACCES; +} +static void hook_audit_rule_free(void *lsmrule){ + struct judgk_proc_info *info; + + info = judgk_proc_task_lookup(current); + if(likely(info == NULL || in_interrupt())){ + return ori_sops->audit_rule_free(lsmrule); + } + + pr_alert("judgk:PID %d audit_rule_free\n",current->tgid); + + security_hook_rf(info); +} diff --git a/toj/center/src/judgk_security.h b/toj/center/src/judgk_security.h new file mode 100755 index 0000000..5080dd0 --- /dev/null +++ b/toj/center/src/judgk_security.h @@ -0,0 +1,197 @@ +static unsigned long* security_get_addr(void); +static inline void security_hook_rf(struct judgk_proc_info *info); + +static unsigned long* security_hook_addr; +static struct security_operations *ori_sops; +static struct security_operations hook_sops; + +int judgk_security_hook(void); +int judgk_security_unhook(void); + +extern struct judgk_proc_info* judgk_proc_task_lookup(struct task_struct *task); + +static int hook_ptrace_access_check(struct task_struct *child,unsigned int mode); +static int hook_ptrace_traceme(struct task_struct *parent); +static int hook_capget(struct task_struct *target,kernel_cap_t *effective,kernel_cap_t *inheritable,kernel_cap_t *permitted); +static int hook_capset(struct cred *new,const struct cred *old,const kernel_cap_t *effective,const kernel_cap_t *inheritable,const kernel_cap_t *permitted); +//static int hook_capable(const struct cred *cred,struct user_namespace *ns,int cap,int audit); +static int hook_quotactl(int cmds,int type,int id,struct super_block *sb); +static int hook_quota_on(struct dentry *dentry); +static int hook_syslog(int type); +static int hook_settime(const struct timespec *ts,const struct timezone *tz); +static int hook_vm_enough_memory(struct mm_struct *mm,long pages); +//static int hook_bprm_set_creds(struct linux_binprm *bprm); +//static int hook_bprm_check_security(struct linux_binprm *bprm); +//static int hook_bprm_secureexec(struct linux_binprm *bprm); +//static void hook_bprm_committing_creds(struct linux_binprm *bprm); +//static void hook_bprm_committed_creds(struct linux_binprm *bprm); +static int hook_sb_alloc_security(struct super_block *sb); +static void hook_sb_free_security(struct super_block *sb); +static int hook_sb_copy_data(char *orig,char *copy); +static int hook_sb_remount(struct super_block *sb,void *data); +static int hook_sb_kern_mount(struct super_block *sb,int flags,void *data); +static int hook_sb_show_options(struct seq_file *m,struct super_block *sb); +static int hook_sb_statfs(struct dentry *dentry); +static int hook_sb_mount(const char *dev_name,struct path *path,const char *type,unsigned long flags,void *data); +static int hook_sb_umount(struct vfsmount *mnt,int flags); +static int hook_sb_pivotroot(struct path *old_path,struct path *new_path); +static int hook_sb_set_mnt_opts(struct super_block *sb,struct security_mnt_opts *opts); +static void hook_sb_clone_mnt_opts(const struct super_block *oldsb,struct super_block *newsb); +static int hook_sb_parse_opts_str(char *options,struct security_mnt_opts *opts); +static int hook_path_unlink(struct path *dir,struct dentry *dentry); +static int hook_path_mkdir(struct path *dir,struct dentry *dentry,umode_t mode); +static int hook_path_rmdir(struct path *dir,struct dentry *dentry); +static int hook_path_mknod(struct path *dir,struct dentry *dentry,umode_t mode,unsigned int dev); +static int hook_path_truncate(struct path *path); +static int hook_path_symlink(struct path *dir,struct dentry *dentry,const char *old_name); +static int hook_path_link(struct dentry *old_dentry,struct path *new_dir,struct dentry *new_dentry); +static int hook_path_rename(struct path *old_dir,struct dentry *old_dentry,struct path *new_dir,struct dentry *new_dentry); +static int hook_path_chmod(struct path *path,umode_t mode); +static int hook_path_chown(struct path *path,kuid_t uid,kgid_t gid); +static int hook_path_chroot(struct path *path); +//static int hook_inode_alloc_security(struct inode *inode); +//static void hook_inode_free_security(struct inode *inode); +static int hook_inode_init_security(struct inode *inode,struct inode *dir,const struct qstr *qstr,char **name,void **value,size_t *len); +static int hook_inode_create(struct inode *dir,struct dentry *dentry,umode_t mode); +static int hook_inode_link(struct dentry *old_dentry,struct inode *dir,struct dentry *new_dentry); +static int hook_inode_unlink(struct inode *dir,struct dentry *dentry); +static int hook_inode_symlink(struct inode *dir,struct dentry *dentry,const char *old_name); +static int hook_inode_mkdir(struct inode *dir,struct dentry *dentry,umode_t mode); +static int hook_inode_rmdir(struct inode *dir,struct dentry *dentry); +static int hook_inode_mknod(struct inode *dir,struct dentry *dentry,umode_t mode,dev_t dev); +static int hook_inode_rename(struct inode *old_dir,struct dentry *old_dentry,struct inode *new_dir,struct dentry *new_dentry); +static int hook_inode_readlink(struct dentry *dentry); +//static int hook_inode_follow_link(struct dentry *dentry,struct nameidata *nd); +static int hook_inode_permission(struct inode *inode,int mask); +static int hook_inode_setattr(struct dentry *dentry,struct iattr *attr); +//static int hook_inode_getattr(struct vfsmount *mnt,struct dentry *dentry); +static int hook_inode_setxattr(struct dentry *dentry,const char *name,const void *value,size_t size,int flags); +static void hook_inode_post_setxattr(struct dentry *dentry,const char *name,const void *value,size_t size,int flags); +static int hook_inode_getxattr(struct dentry *dentry,const char *name); +static int hook_inode_listxattr(struct dentry *dentry); +static int hook_inode_removexattr(struct dentry *dentry,const char *name); +static int hook_inode_need_killpriv(struct dentry *dentry); +static int hook_inode_killpriv(struct dentry *dentry); +static int hook_inode_getsecurity(const struct inode *inode,const char *name,void **buffer,bool alloc); +static int hook_inode_setsecurity(struct inode *inode,const char *name,const void *value,size_t size,int flags); +static int hook_inode_listsecurity(struct inode *inode,char *buffer,size_t buffer_size); +static void hook_inode_getsecid(const struct inode *inode,u32 *secid); +static int hook_file_permission(struct file *file,int mask); +//static int hook_file_alloc_security(struct file *file); +//static void hook_file_free_security(struct file *file); +static int hook_file_ioctl(struct file *file,unsigned int cmd,unsigned long arg); +//static int hook_mmap_addr(unsigned long addr); +//static int hook_mmap_file(struct file *file,unsigned long reqprot,unsigned long prot,unsigned long flags); +//static int hook_file_mprotect(struct vm_area_struct *vma,unsigned long reqprot,unsigned long prot); +static int hook_file_lock(struct file *file,unsigned int cmd); +static int hook_file_fcntl(struct file *file,unsigned int cmd,unsigned long arg); +static int hook_file_set_fowner(struct file *file); +static int hook_file_send_sigiotask(struct task_struct *tsk,struct fown_struct *fown,int sig); +static int hook_file_receive(struct file *file); +static int hook_file_open(struct file *file,const struct cred *cred); +static int hook_task_create(unsigned long clone_flags); +//static void hook_task_free(struct task_struct *task); +static int hook_cred_alloc_blank(struct cred *cred,gfp_t gfp); +//static void hook_cred_free(struct cred *cred); +//static int hook_cred_prepare(struct cred *new,const struct cred *old,gfp_t gfp); +static void hook_cred_transfer(struct cred *new,const struct cred *old); +static int hook_kernel_act_as(struct cred *new,u32 secid); +static int hook_kernel_create_files_as(struct cred *new,struct inode *inode); +static int hook_kernel_module_request(char *kmod_name); +static int hook_task_fix_setuid(struct cred *new,const struct cred *old,int flags); +static int hook_task_setpgid(struct task_struct *p,pid_t pgid); +static int hook_task_getpgid(struct task_struct *p); +static int hook_task_getsid(struct task_struct *p); +static void hook_task_getsecid(struct task_struct *p,u32 *secid); +static int hook_task_setnice(struct task_struct *p,int nice); +static int hook_task_setioprio(struct task_struct *p,int ioprio); +static int hook_task_getioprio(struct task_struct *p); +static int hook_task_setrlimit(struct task_struct *p,unsigned int resource,struct rlimit *new_rlim); +static int hook_task_setscheduler(struct task_struct *p); +static int hook_task_getscheduler(struct task_struct *p); +static int hook_task_movememory(struct task_struct *p); +static int hook_task_kill(struct task_struct *p,struct siginfo *siginfo,int sig,u32 secid); +static int hook_task_wait(struct task_struct *p); +static int hook_task_prctl(int option,unsigned long arg2,unsigned long arg3,unsigned long arg4,unsigned long arg5); +static void hook_task_to_inode(struct task_struct *p,struct inode *inode); +static int hook_ipc_permission(struct kern_ipc_perm *ipcp,short flag); +static void hook_ipc_getsecid(struct kern_ipc_perm *ipcp,u32 *secid); +static int hook_msg_msg_alloc_security(struct msg_msg *msg); +static void hook_msg_msg_free_security(struct msg_msg *msg); +static int hook_msg_queue_alloc_security(struct msg_queue *msq); +static void hook_msg_queue_free_security(struct msg_queue *msq); +static int hook_msg_queue_associate(struct msg_queue *msq,int msqflg); +static int hook_msg_queue_msgctl(struct msg_queue *msq,int cmd); +static int hook_msg_queue_msgsnd(struct msg_queue *msq,struct msg_msg *msg,int msqflg); +static int hook_msg_queue_msgrcv(struct msg_queue *msq,struct msg_msg *msg,struct task_struct *target,long type,int mode); +static int hook_shm_alloc_security(struct shmid_kernel *shp); +static void hook_shm_free_security(struct shmid_kernel *shp); +static int hook_shm_associate(struct shmid_kernel *shp,int shmflg); +static int hook_shm_shmctl(struct shmid_kernel *shp,int cmd); +static int hook_shm_shmat(struct shmid_kernel *shp,char __user *shmaddr,int shmflg); +static int hook_sem_alloc_security(struct sem_array *sma); +static void hook_sem_free_security(struct sem_array *sma); +static int hook_sem_associate(struct sem_array *sma,int semflg); +static int hook_sem_semctl(struct sem_array *sma,int cmd); +static int hook_sem_semop(struct sem_array *sma,struct sembuf *sops,unsigned nsops,int alter); +static int hook_netlink_send(struct sock *sk,struct sk_buff *skb); +static void hook_d_instantiate(struct dentry *dentry,struct inode *inode); +static int hook_getprocattr(struct task_struct *p,char *name,char **value); +static int hook_setprocattr(struct task_struct *p,char *name,void *value,size_t size); +static int hook_secid_to_secctx(u32 secid,char **secdata,u32 *seclen); +static int hook_secctx_to_secid(const char *secdata,u32 seclen,u32 *secid); +static void hook_release_secctx(char *secdata,u32 seclen); +static int hook_inode_notifysecctx(struct inode *inode,void *ctx,u32 ctxlen); +static int hook_inode_setsecctx(struct dentry *dentry,void *ctx,u32 ctxlen); +static int hook_inode_getsecctx(struct inode *inode,void **ctx,u32 *ctxlen); +static int hook_unix_stream_connect(struct sock *sock,struct sock *other,struct sock *newsk); +static int hook_unix_may_send(struct socket *sock,struct socket *other); +static int hook_socket_create(int family,int type,int protocol,int kern); +static int hook_socket_post_create(struct socket *sock,int family,int type,int protocol,int kern); +static int hook_socket_bind(struct socket *sock,struct sockaddr *address,int addrlen); +static int hook_socket_connect(struct socket *sock,struct sockaddr *address,int addrlen); +static int hook_socket_listen(struct socket *sock,int backlog); +static int hook_socket_accept(struct socket *sock,struct socket *newsock); +static int hook_socket_sendmsg(struct socket *sock,struct msghdr *msg,int size); +static int hook_socket_recvmsg(struct socket *sock,struct msghdr *msg,int size,int flags); +static int hook_socket_getsockname(struct socket *sock); +static int hook_socket_getpeername(struct socket *sock); +static int hook_socket_getsockopt(struct socket *sock,int level,int optname); +static int hook_socket_setsockopt(struct socket *sock,int level,int optname); +static int hook_socket_shutdown(struct socket *sock,int how); +static int hook_socket_sock_rcv_skb(struct sock *sk,struct sk_buff *skb); +static int hook_socket_getpeersec_stream(struct socket *sock,char __user *optval,int __user *optlen,unsigned len); +static int hook_socket_getpeersec_dgram(struct socket *sock,struct sk_buff *skb,u32 *secid); +static int hook_sk_alloc_security(struct sock *sk,int family,gfp_t priority); +static void hook_sk_free_security(struct sock *sk); +static void hook_sk_clone_security(const struct sock *sk,struct sock *newsk); +static void hook_sk_getsecid(struct sock *sk,u32 *secid); +static void hook_sock_graft(struct sock *sk,struct socket *parent); +static int hook_inet_conn_request(struct sock *sk,struct sk_buff *skb,struct request_sock *req); +static void hook_inet_csk_clone(struct sock *newsk,const struct request_sock *req); +static void hook_inet_conn_established(struct sock *sk,struct sk_buff *skb); +static int hook_secmark_relabel_packet(u32 secid); +static void hook_secmark_refcount_inc(void); +static void hook_secmark_refcount_dec(void); +static void hook_req_classify_flow(const struct request_sock *req,struct flowi *fl); +static int hook_tun_dev_create(void); +static void hook_tun_dev_post_create(struct sock *sk); +static int hook_tun_dev_attach(struct sock *sk); +/*static int hook_xfrm_policy_alloc_security(struct xfrm_sec_ctx **ctxp,struct xfrm_user_sec_ctx *sec_ctx); +static int hook_xfrm_policy_clone_security(struct xfrm_sec_ctx *old_ctx,struct xfrm_sec_ctx **new_ctx); +static void hook_xfrm_policy_free_security(struct xfrm_sec_ctx *ctx); +static int hook_xfrm_policy_delete_security(struct xfrm_sec_ctx *ctx); +static int hook_xfrm_state_alloc_security(struct xfrm_state *x,struct xfrm_user_sec_ctx *sec_ctx,u32 secid); +static void hook_xfrm_state_free_security(struct xfrm_state *x); +static int hook_xfrm_state_delete_security(struct xfrm_state *x); +static int hook_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx,u32 fl_secid,u8 dir); +static int hook_xfrm_state_pol_flow_match(struct xfrm_state *x,struct xfrm_policy *xp,const struct flowi *fl); +static int hook_xfrm_decode_session(struct sk_buff *skb,u32 *secid,int ckall);*/ +static int hook_key_alloc(struct key *key,const struct cred *cred,unsigned long flags); +static void hook_key_free(struct key *key); +static int hook_key_permission(key_ref_t key_ref,const struct cred *cred,key_perm_t perm); +static int hook_key_getsecurity(struct key *key,char **_buffer); +static int hook_audit_rule_init(u32 field,u32 op,char *rulestr,void **lsmrule); +static int hook_audit_rule_known(struct audit_krule *krule); +static int hook_audit_rule_match(u32 secid,u32 field,u32 op,void *lsmrule,struct audit_context *actx); +static void hook_audit_rule_free(void *lsmrule); diff --git a/toj/center/src/judgk_syscall.c b/toj/center/src/judgk_syscall.c new file mode 100755 index 0000000..370a3fe --- /dev/null +++ b/toj/center/src/judgk_syscall.c @@ -0,0 +1,240 @@ +#include +#include +#include +#include +#include +#include +#include + +#include"judge_def.h" +#include"judgk.h" +#include"judgk_com.h" +#include"judgk_syscall.h" + +int judgk_syscall_hook(){ + int i; + int j; + + unsigned int size; + unsigned int restore; + + syscall_init_hook(); + + syscall_addr_write((unsigned long)syscall_table,&size,&restore); + for(i = 0,j = 0;i < syscall_max;i++){ + if(size == 0){ + syscall_addr_restore((unsigned long)(syscall_table + i - 1),restore); + syscall_addr_write((unsigned long)(syscall_table + i),&size,&restore); + } + size -= sizeof(unsigned long); + + if(i == syscall_whitelist[j]){ + j++; + continue; + } + syscall_table[i] = (unsigned long)hook_sys_block; + } + syscall_addr_restore((unsigned long)(&syscall_table[i - 1]),restore); + + return 0; +} +int judgk_syscall_unhook(){ + int i; + + unsigned int size; + unsigned int restore; + + syscall_addr_write((unsigned long)syscall_table,&size,&restore); + for(i = 0;i < syscall_max;i++){ + if(size == 0){ + syscall_addr_restore((unsigned long)(&syscall_table[i - 1]),restore); + syscall_addr_write((unsigned long)(&syscall_table[i]),&size,&restore); + } + size -= sizeof(unsigned long); + + syscall_table[i] = (unsigned long)judgk_syscall_ori_table[i]; + } + syscall_addr_restore((unsigned long)(&syscall_table[i - 1]),restore); + + kfree(judgk_syscall_ori_table); + return 0; +} +static int syscall_init_hook(){ + ssize_t ret; + int i; + int j; + + struct file *f; + char line[128]; + unsigned char code[3] = {0xff,0x14,0xc5}; + unsigned long addr; + + f = filp_open("/proc/kallsyms",O_RDONLY,0); + set_fs(KERNEL_DS); + + i = 0; + addr = 0; + while(true){ + ret = f->f_op->read(f,&line[i],1,&f->f_pos); + + if(line[i] == '\n' || ret <= 0){ + line[i] = '\0'; + + addr = 0; + for(j = 0;j < i;j++){ + if(line[j] == ' '){ + j++; + break; + } + + addr *= 16UL; + if(line[j] >= '0' && line[j] <= '9'){ + addr += (unsigned long)(line[j] - '0'); + }else{ + addr += (unsigned long)(line[j] - 'a' + 10); + } + } + for(;j < i;j++){ + if(line[j] == ' '){ + j++; + break; + } + } + if(j < i){ + if(strcmp("system_call",line + j) == 0){ + break; + } + } + + i = 0; + }else{ + i++; + } + + if(ret <= 0){ + break; + } + } + + set_fs(USER_DS); + filp_close(f,NULL); + + while(true){ + for(i = 0;i < 3;i++){ + if(*(unsigned char*)addr != code[i]){ + addr++; + break; + } + addr++; + } + if(i == 3){ + break; + } + } + syscall_table = (unsigned long*)(0xffffffff00000000 + *((unsigned int*)addr)); + + addr -= 4L; + while(true){ + if(*(unsigned char*)addr == 0x3d){ + addr++; + break; + } + addr--; + } + syscall_max = *(unsigned int*)addr; + + judgk_syscall_ori_table = kmalloc(sizeof(unsigned long) * (syscall_max + 1),GFP_KERNEL); + memcpy(judgk_syscall_ori_table,syscall_table,sizeof(unsigned long) * syscall_max); + + sort(syscall_whitelist,SYSCALL_WHITELIST_SIZE,sizeof(unsigned int),syscall_whitelist_cmp,NULL); + + return 0; +} +static int syscall_whitelist_cmp(const void *a,const void *b){ + if(*(unsigned int*)a < *(unsigned int*)b){ + return -1; + }else if(*(unsigned int*)a == *(unsigned int*)b){ + return 0; + }else{ + return 1; + } +} +static int syscall_addr_write(unsigned long addr,unsigned int *size,int *restore){ + unsigned int level; + pte_t *pte; + + pte = lookup_address(addr,&level); + if(pte->pte & _PAGE_RW){ + *restore = 0; + }else{ + pte->pte |= _PAGE_RW; + *restore = 1; + } + + switch(level){ + case PG_LEVEL_4K: + *size = 4096; + break; + case PG_LEVEL_2M: + *size = 2097152; + break; + case PG_LEVEL_1G: + *size = 1073741824; + break; + } + *size -= (((unsigned int)addr) & (*size - 1)); + + return 0; +} +static int syscall_addr_restore(unsigned long addr,int restore){ + unsigned int level; + pte_t *pte; + + if(restore){ + pte = lookup_address(addr,&level); + pte->pte ^= _PAGE_RW; + } + + return 0; +} + +int judgk_syscall_check(){ + if(judgk_proc_task_lookup(current)){ + return 1; + } + return 0; +} +int judgk_syscall_block(){ + struct judgk_proc_info *info; + + if((info = judgk_proc_task_lookup(current)) == NULL){ + return 0; + } + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return 0; +} + +/*asmlinkage long hook_sys_nanosleep(struct timespec __user *rqtp,struct timespec __user *rmtp){ + long ret; + + struct judgm_proc_info *info; + + atomic64_inc(&syscall_pending); + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + ret = ori_sys_nanosleep(rqtp,rmtp); + atomic64_dec(&syscall_pending); + return ret; + } + + pr_alert("judgm:PID %d nanosleep\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + + atomic64_dec(&syscall_pending); + return -EACCES; +}*/ diff --git a/toj/center/src/judgk_syscall.h b/toj/center/src/judgk_syscall.h new file mode 100755 index 0000000..2ee6afb --- /dev/null +++ b/toj/center/src/judgk_syscall.h @@ -0,0 +1,70 @@ +#define SYSCALL_WHITELIST_SIZE 45 + +static int syscall_init_hook(void); +static int syscall_whitelist_cmp(const void *a,const void *b); +static int syscall_addr_write(unsigned long addr,unsigned int *size,int *restore); +static int syscall_addr_restore(unsigned long addr,int restore); + +static unsigned long* syscall_table; +static unsigned int syscall_max; +static unsigned int syscall_whitelist[SYSCALL_WHITELIST_SIZE] = { + __NR_execve, + __NR_open, + __NR_creat, + __NR_unlink, + __NR_access, + __NR_truncate, + __NR_stat, + __NR_lstat, + __NR_readlink, + __NR_exit, + __NR_read, + __NR_write, + __NR_close, + __NR_lseek, + __NR_getpid, + __NR_getuid, + __NR_dup, + __NR_brk, + __NR_getgid, + __NR_geteuid, + __NR_getegid, + __NR_dup2, + __NR_ftruncate, + __NR_fstat, + __NR_personality, + __NR_readv, + __NR_writev, + __NR_getresuid, + __NR_pread64, + __NR_pwrite64, + __NR_fcntl, + __NR_mmap, + __NR_munmap, + __NR_ioctl, + __NR_uname, + __NR_gettid, + __NR_set_thread_area, + __NR_get_thread_area, + __NR_set_tid_address, + __NR_exit_group, + __NR_arch_prctl, + __NR_times, + __NR_time, + __NR_clock_gettime, + __NR_dup3 +}; + +int judgk_syscall_hook(void); +int judgk_syscall_unhook(void); +int judgk_syscall_check(void); +int judgk_syscall_block(void); + +unsigned long *judgk_syscall_ori_table; + +extern struct judgk_proc_info* judgk_proc_task_lookup(struct task_struct *task); +extern long hook_sys_block(void); + +//typedef asmlinkage long (*func_sys_nanosleep)(struct timespec __user *rqtp,struct timespec __user *rmtp); +//func_sys_nanosleep ori_sys_nanosleep; +//asmlinkage long hook_sys_nanosleep(struct timespec __user *rqtp,struct timespec __user *rmtp); diff --git a/toj/center/src/judgk_syscall_asm.S b/toj/center/src/judgk_syscall_asm.S new file mode 100755 index 0000000..dfc5bc6 --- /dev/null +++ b/toj/center/src/judgk_syscall_asm.S @@ -0,0 +1,54 @@ +.code64 +.section .data +.section .text +.global hook_sys_block +.type hook_sys_block,@function + +hook_sys_block: + push %rax + push %rbx + push %rcx + push %rdx + push %rsi + push %rdi + push %rbp + push %r8 + push %r9 + push %r10 + push %r11 + push %r12 + push %r13 + push %r14 + push %r15 + + call judgk_syscall_check + test %eax,%eax + + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %r11 + pop %r10 + pop %r9 + pop %r8 + pop %rbp + pop %rdi + pop %rsi + pop %rdx + pop %rcx + pop %rbx + pop %rax + + jnz block + + push %rdx + mov $8,%rdx + mul %rdx + pop %rdx + add judgk_syscall_ori_table,%rax + jmp *(%rax) +block: + call judgk_syscall_block + mov $-1,%rax + ret diff --git a/toj/center/src/judgm_lib.h b/toj/center/src/judgm_lib.h new file mode 100644 index 0000000..324147e --- /dev/null +++ b/toj/center/src/judgm_lib.h @@ -0,0 +1,369 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include"judgk_com.h" + +typedef int (*judgm_proc_check_fn)(); + +class judgm_proc{ +private: + int init(){ + int i; + int j; + struct stat st; + + if(stat(exe_path,&st)){ + return -1; + } + if(!S_ISREG(st.st_mode)){ + return -1; + } + + exe_name[NAME_MAX] = '\0'; + for(i = 0,j = 0;exe_path[i] != '\0' && j < NAME_MAX;i++){ + if(exe_path[i] == '/'){ + j = 0; + }else{ + exe_name[j] = exe_path[i]; + j++; + } + } + exe_name[j] = '\0'; + + pid = 0; + kern_task = 0; + status = JUDGE_WAIT; + runtime = 0; + memory = 0; + + return 0; + } + int protect(){ + rlimit limit; + judgk_com_proc_add com_proc_add; + + limit.rlim_cur = 1; + limit.rlim_max = limit.rlim_cur; + prlimit(pid,RLIMIT_NPROC,&limit,NULL); + + limit.rlim_cur = 8L; + limit.rlim_max = limit.rlim_cur; + prlimit(pid,RLIMIT_NOFILE,&limit,NULL); + + com_proc_add.run_path[0] = '\0'; + strncat(com_proc_add.run_path,run_path,sizeof(com_proc_add.run_path)); + com_proc_add.pid = pid; + com_proc_add.timelimit = timelimit * 1000L; + com_proc_add.hardtimelimit = hardtimelimit * 1000L; + com_proc_add.memlimit = memlimit * 1024L + 4096L * 128L; + if(ioctl(judgk_modfd,IOCTL_PROC_ADD,&com_proc_add)){ + return -1; + } + kern_task = com_proc_add.kern_task; + + return 0; + } + +public: + int judgk_modfd; + char run_path[PATH_MAX + 1]; + char exe_path[PATH_MAX + 1]; + char exe_name[NAME_MAX + 1]; + unsigned long timelimit; + unsigned long hardtimelimit; + unsigned long memlimit; + judgm_proc_check_fn check_fn; + + pid_t pid; + unsigned long kern_task; + int status; + unsigned long runtime; + unsigned long memory; + + judgm_proc(int judgk_modfd,char *runpath,char *exe_path,unsigned long timelimit,unsigned long hardtimelimit,unsigned long memlimit,judgm_proc_check_fn check_fn){ + this->judgk_modfd = judgk_modfd; + this->run_path[0] = '\0'; + strncat(this->run_path,runpath,sizeof(this->run_path)); + this->exe_path[0] = '\0'; + strncat(this->exe_path,exe_path,sizeof(this->exe_path)); + + this->timelimit = timelimit; + this->hardtimelimit = hardtimelimit; + this->memlimit = memlimit; + this->check_fn = check_fn; + } + + int proc_run(){ + char abspath[PATH_MAX + 1]; + + if(init()){ + return -1; + } + + realpath(exe_path,abspath); + if((pid = fork()) == 0){ + char *argv[] = {NULL,NULL}; + char *envp[] = {NULL}; + + chdir(run_path); + check_fn(); + + setgid(99); + setuid(99); + kill(getpid(),SIGSTOP); + + argv[0] = exe_name; + execve(abspath,argv,envp); + exit(0); + } + + if(pid == -1){ + return -1; + } + waitpid(pid,NULL,WUNTRACED); + + if(protect()){ + kill(pid,SIGKILL); + return -1; + } + status = JUDGE_RUN; + kill(pid,SIGCONT); + + return 0; + } + int proc_wait(bool blockflag){ + int wstatus; + struct judgk_com_proc_get com_proc_get; + + if(blockflag == true){ + if(waitpid(pid,&wstatus,WUNTRACED) == -1){ + return -1; + } + }else{ + if(waitpid(pid,&wstatus,WUNTRACED | WNOHANG) <= 0){ + return -1; + } + } + + com_proc_get.kern_task = kern_task; + if(ioctl(judgk_modfd,IOCTL_PROC_GET,&com_proc_get)){ + return -1; + } + + runtime = com_proc_get.runtime / 1000L; + memory = com_proc_get.memory; + + printf("runtime:%lu memory:%lu\n",runtime,memory); + + if(com_proc_get.status != JUDGE_AC){ + status = com_proc_get.status; + }else if(memory > (memlimit * 1024L)){ + status = JUDGE_MLE; + }else if(runtime > timelimit){ + status = JUDGE_TLE; + }else if(WIFEXITED(wstatus) || (WIFSIGNALED(wstatus) && WTERMSIG(wstatus) == SIGKILL)){ + status = JUDGE_AC; + }else{ + status = JUDGE_RE; + } + + return 0; + } + int proc_kill(){ + if(kill(pid,SIGKILL)){ + return -1; + } + return 0; + } +}; + +class judgm_hyperio{ +private: + int judgk_modfd; + char *read_buf; + off_t read_off; + +public: + int tty_idx; + + judgm_hyperio(int judgk_modfd){ + this->judgk_modfd = judgk_modfd; + this->tty_idx = ioctl(this->judgk_modfd,IOCTL_HYPERIO_ADD,0); + this->read_buf = (char*)mmap(NULL,JUDGK_COM_HYPERIO_BUFSIZE,PROT_READ,MAP_SHARED,judgk_modfd,0); + this->read_off = 0; + } + ~judgm_hyperio(){ + munmap(read_buf,JUDGK_COM_HYPERIO_BUFSIZE); + ioctl(judgk_modfd,IOCTL_HYPERIO_DEL,0); + } + + static int get_ttyfd(int idx){ + char tpath[PATH_MAX + 1]; + + snprintf(tpath,sizeof(tpath),"/dev/jtty%d",idx); + return open(tpath,O_RDWR); + } + size_t wait(){ + return ioctl(judgk_modfd,IOCTL_HYPERIO_READ,0); + } + int compare(char *buf,size_t len){ + int flag; + size_t remain; + off_t off; + size_t data_len; + size_t cmp_len; + + flag = 0; + remain = len; + off = 0; + data_len = 0; + cmp_len = 0; + while(remain > 0 && flag == 0){ + if(data_len == 0){ + if((data_len = ioctl(judgk_modfd,IOCTL_HYPERIO_READ,cmp_len)) <= 0){ + return -1; + } + } + if(remain < data_len){ + cmp_len = remain; + }else{ + cmp_len = data_len; + } + + if((cmp_len + read_off) < JUDGK_COM_HYPERIO_BUFSIZE){ + flag |= memcmp(read_buf + read_off,buf + off,cmp_len); + read_off += cmp_len; + }else{ + flag |= memcmp(read_buf + read_off,buf + off,JUDGK_COM_HYPERIO_BUFSIZE - read_off); + flag |= memcmp(read_buf,buf + off + (JUDGK_COM_HYPERIO_BUFSIZE - read_off),(cmp_len + read_off) - JUDGK_COM_HYPERIO_BUFSIZE); + read_off = (cmp_len + read_off) - JUDGK_COM_HYPERIO_BUFSIZE; + } + remain -= cmp_len; + off += cmp_len; + data_len -= cmp_len; + } + if(cmp_len > 0){ + ioctl(judgk_modfd,IOCTL_HYPERIO_READ,-(long)cmp_len); + } + + if(flag == 0){ + return 0; + }else{ + return -1; + } + } +}; + +static int judgm_compile(int subid,char *code_path,char *exe_path,int lang,bool force_flag,char *errmsg,size_t errsize){ + int ret; + int i; + + char main_path[PATH_MAX + 1]; + char sem_path[PATH_MAX + 1]; + struct stat st; + sem_t *wait_sem; + bool ce_flag; + char dir_path[PATH_MAX + 1]; + char *out_path; + int io[2]; + int pid; + int wstatus; + off_t off; + + if(force_flag == false){ + snprintf(main_path,sizeof(main_path),"tmp/exe/%d/main",subid); + snprintf(sem_path,sizeof(sem_path),"/judgm_compile_wait_%d",subid); + if((wait_sem = sem_open(sem_path,0)) == SEM_FAILED){ + if(stat(main_path,&st)){ + if((wait_sem = sem_open(sem_path,O_CREAT | O_EXCL,0644,0)) != SEM_FAILED){ + out_path = main_path; + goto compile; + }else if((wait_sem = sem_open(sem_path,0)) != SEM_FAILED){ + + sem_wait(wait_sem); + + sem_close(wait_sem); + } + } + }else{ + + sem_wait(wait_sem); + + sem_close(wait_sem); + } + + if(!link(main_path,exe_path)){ + return 0; + } + } + + force_flag = true; + out_path = exe_path; + +compile: + + if(force_flag == false){ + snprintf(dir_path,sizeof(dir_path),"tmp/exe/%d",subid); + mkdir(dir_path,0755); + } + ce_flag = false; + + if(lang == JUDGE_CPP){ + pipe(io); + + if((pid = fork()) == 0){ + char *argv[] = {"g++","-static","-O2",code_path,"-std=c++0x","-o",out_path,NULL}; + + dup2(io[1],1); + dup2(io[1],2); + execvp("g++",argv); + } + + close(io[1]); + off = 0; + while((ret = read(io[0],errmsg + off,errsize - off - 1)) > 0){ + off += ret; + } + errmsg[off] = '\0'; + close(io[0]); + + waitpid(pid,&wstatus,0); + if(wstatus != 0){ + ce_flag = true; + } + } + + if(force_flag == false){ + if(ce_flag == true){ + rmdir(dir_path); + } + + for(i = 0;i < 8;i++){ + sem_post(wait_sem); + } + sem_close(wait_sem); + sem_unlink(sem_path); + } + if(ce_flag == true){ + return -1; + } + + link(main_path,exe_path); + + return 0; +} diff --git a/toj/center/src/judgm_line.h b/toj/center/src/judgm_line.h new file mode 100755 index 0000000..1b36c74 --- /dev/null +++ b/toj/center/src/judgm_line.h @@ -0,0 +1,19 @@ +struct judgm_line_info{ + int subid; + + char *pro_path; + char *code_path; + char *run_path; + + int judgk_modfd; + void *line_dll; + void *check_dll; + + int lang; + FILE *set_file; + char *set_data; + + char res_data[JUDGE_RES_DATAMAX]; + size_t res_len; +}; +typedef int (*judgm_line_run_fn)(judgm_line_info *info); diff --git a/toj/center/src/judgm_manage.h b/toj/center/src/judgm_manage.h new file mode 100644 index 0000000..85385e7 --- /dev/null +++ b/toj/center/src/judgm_manage.h @@ -0,0 +1,27 @@ +typedef int (*judgm_manage_queuesubmit_fn)(int subid,int proid,int lang,char *set_data,size_t set_len); + +struct judgm_manage_submitinfo{ + int subid; + int uid; + int proid; + int lang; + char *param; + + char pro_path[PATH_MAX + 1]; + FILE *set_file; +}; +typedef int (*judgm_manage_submit_fn)(judgm_manage_submitinfo *info,void **manage_data); + +struct judgm_manage_resultinfo{ + int subid; + int uid; + int proid; + char *res_path; + char *res_data; + + int result; + double score; + unsigned long runtime; + unsigned long memory; +}; +typedef int (*judgm_manage_result_fn)(judgm_manage_resultinfo *info,void *manage_data); diff --git a/toj/center/src/netio.h b/toj/center/src/netio.h new file mode 100644 index 0000000..db54b23 --- /dev/null +++ b/toj/center/src/netio.h @@ -0,0 +1,192 @@ +class netio_protoiofn{ +public: + virtual void operator()(void *buf,size_t len,void *data) = 0; +}; + +template +class netio_iofn : public netio_protoiofn{ +private: + typedef void (C::*netio_iofn_type)(void *buf,size_t len,void *data); + C *obj; + netio_iofn_type fn; + +public: + netio_iofn(C *obj,netio_iofn_type fn){ + this->obj = obj; + this->fn = fn; + } + void operator()(void *buf,size_t len,void *data){ + (obj->*fn)(buf,len,data); + } +}; + +#define NETIO_IOTYPE_PLAIN 0 +#define NETIO_IOTYPE_FILE 1 +class netio_iocb{ +public: + int type; + + void *buf; + int fd; + off_t off; + size_t len; + netio_protoiofn *cb_fn; + void *cb_data; + + netio_iocb(void *buf,size_t len,netio_protoiofn *cb_fn,void *cb_data){ + this->type = NETIO_IOTYPE_PLAIN; + this->buf = buf; + this->off = 0; + this->len = len; + this->cb_fn = cb_fn; + this->cb_data = cb_data; + } + netio_iocb(int fd,size_t len,netio_protoiofn *cb_fn,void *cb_data){ + this->type = NETIO_IOTYPE_FILE; + this->buf = &this->fd; + this->fd = fd; + this->off = 0; + this->len = len; + this->cb_fn = cb_fn; + this->cb_data = cb_data; + } +}; + +#define NETIO_IOSIZE 65536 +class netio{ +private: + netio_iocb *read_iocb; + std::queue write_queue; + bool readio_reen; + char readio_buf[NETIO_IOSIZE]; + +public: + int fd; + virtual int readidle() = 0; + + netio(int fd){ + this->fd = fd; + this->read_iocb = NULL; + this->readio_reen = false; + } + ~netio(){ + close(this->fd); + } + int readio(){ + int ret; + size_t len; + netio_iocb *iocb; + + if(readio_reen == true){ + return -1; + } + readio_reen = true; + + while(true){ + if(read_iocb == NULL){ + readidle(); + } + + iocb = read_iocb; + if(iocb->type == NETIO_IOTYPE_PLAIN){ + while((ret = read(fd,(char*)iocb->buf + iocb->off,iocb->len - iocb->off)) > 0){ + iocb->off += ret; + } + }else if(iocb->type == NETIO_IOTYPE_FILE){ + while(true){ + len = iocb->len - iocb->off; + if(len >= NETIO_IOSIZE){ + len = NETIO_IOSIZE; + } + if((ret = read(fd,readio_buf,len)) <= 0){ + break; + } + + write(iocb->fd,readio_buf,ret); + iocb->off += ret; + } + } + if(iocb->off == iocb->len){ + read_iocb = NULL; + + if(iocb->cb_fn != NULL){ + (*iocb->cb_fn)(iocb->buf,iocb->len,iocb->cb_data); + }else{ + if(iocb->type == NETIO_IOTYPE_PLAIN){ + delete (char*)iocb->buf; + }else if(iocb->type == NETIO_IOTYPE_FILE){ + close(iocb->fd); + } + } + + delete iocb; + }else{ + break; + } + } + + readio_reen = false; + return 0; + } + int readbytes(void *buf,size_t len,netio_protoiofn *cb_fn,void *cb_data){ + read_iocb = new netio_iocb(buf,len,cb_fn,cb_data); + readio(); + return 0; + } + int readfile(int fd,size_t len,netio_protoiofn *cb_fn,void *cb_data){ + read_iocb = new netio_iocb(fd,len,cb_fn,cb_data); + readio(); + return 0; + } + int writeio(){ + int ret; + size_t len; + netio_iocb *iocb; + + while(!write_queue.empty()){ + iocb = write_queue.front(); + if(iocb->type == NETIO_IOTYPE_PLAIN){ + while((ret = write(fd,(char*)iocb->buf + iocb->off,iocb->len - iocb->off)) > 0){ + iocb->off += ret; + } + }else if(iocb->type == NETIO_IOTYPE_FILE){ + len = iocb->len - iocb->off; + if(len >= NETIO_IOSIZE){ + len = NETIO_IOSIZE; + } + while((ret = sendfile(fd,iocb->fd,NULL,len)) > 0){ + iocb->off += ret; + } + } + if(iocb->off == iocb->len){ + write_queue.pop(); + + if(iocb->cb_fn != NULL){ + (*iocb->cb_fn)(iocb->buf,iocb->len,iocb->cb_data); + }else{ + if(iocb->type == NETIO_IOTYPE_PLAIN){ + delete (char*)iocb->buf; + }else if(iocb->type == NETIO_IOTYPE_FILE){ + close(iocb->fd); + } + } + + delete iocb; + }else{ + break; + } + } + + return 0; + } + int writebytes(void *buf,size_t len,netio_protoiofn *cb_fn,void *cb_data){ + write_queue.push(new netio_iocb(buf,len,cb_fn,cb_data)); + writeio(); + return 0; + } + int writefile(int fd,size_t len,netio_protoiofn *cb_fn,void *cb_data){ + write_queue.push(new netio_iocb(fd,len,cb_fn,cb_data)); + writeio(); + return 0; + } +}; diff --git a/toj/center/src/pack.cpp b/toj/center/src/pack.cpp new file mode 100644 index 0000000..c2206b1 --- /dev/null +++ b/toj/center/src/pack.cpp @@ -0,0 +1,175 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include"pack.h" + +static int pack_copenfn(const char *pathname,int flags,...){ + int fd; + pack_bzinfo *bzinfo; + + if((fd = open(pathname,flags,0644)) == -1){ + return -1; + } + + bzinfo = new pack_bzinfo; + bzinfo->len = 0; + bzinfo->off = 0; + bzinfo->endflag = false; + bzinfo->bzs.bzalloc = NULL; + bzinfo->bzs.bzfree = NULL; + bzinfo->bzs.opaque = NULL; + BZ2_bzCompressInit(&bzinfo->bzs,9,0,0); + + pack_fdmap.insert(std::pair(fd,bzinfo)); + + return fd; +} +static int pack_cclosefn(long fd){ + int ret; + pack_bzinfo *bzinfo; + + bzinfo = pack_fdmap.find(fd)->second; + pack_fdmap.erase(fd); + + bzinfo->bzs.next_in = NULL; + bzinfo->bzs.avail_in = 0; + while(true){ + bzinfo->bzs.next_out = bzinfo->buf; + bzinfo->bzs.avail_out = PACK_BUFSIZE; + ret = BZ2_bzCompress(&bzinfo->bzs,BZ_FINISH); + + if(bzinfo->bzs.avail_out != PACK_BUFSIZE){ + write(fd,bzinfo->buf,PACK_BUFSIZE - bzinfo->bzs.avail_out); + } + if(ret == BZ_STREAM_END){ + break; + } + } + + BZ2_bzCompressEnd(&bzinfo->bzs); + delete bzinfo; + return close(fd); +} +static ssize_t pack_cwritefn(long fd,const void *buf,size_t count){ + pack_bzinfo *bzinfo; + + bzinfo = pack_fdmap.find(fd)->second; + + bzinfo->bzs.next_in = (char*)buf; + bzinfo->bzs.avail_in = count; + while(bzinfo->bzs.avail_in > 0){ + bzinfo->bzs.next_out = bzinfo->buf; + bzinfo->bzs.avail_out = PACK_BUFSIZE; + BZ2_bzCompress(&bzinfo->bzs,BZ_RUN); + if(bzinfo->bzs.avail_out != PACK_BUFSIZE){ + write(fd,bzinfo->buf,PACK_BUFSIZE - bzinfo->bzs.avail_out); + } + } + + return count; +} +static int pack_xopenfn(const char *pathname,int flags,...){ + int fd; + pack_bzinfo *bzinfo; + + if((fd = open(pathname,flags)) == -1){ + return -1; + } + + bzinfo = new pack_bzinfo; + bzinfo->len = 0; + bzinfo->off = 0; + bzinfo->endflag = false; + bzinfo->bzs.bzalloc = NULL; + bzinfo->bzs.bzfree = NULL; + bzinfo->bzs.opaque = NULL; + BZ2_bzDecompressInit(&bzinfo->bzs,0,0); + + pack_fdmap.insert(std::pair(fd,bzinfo)); + + return fd; +} +static int pack_xclosefn(long fd){ + int ret; + pack_bzinfo *bzinfo; + + bzinfo = pack_fdmap.find(fd)->second; + pack_fdmap.erase(fd); + BZ2_bzDecompressEnd(&bzinfo->bzs); + delete bzinfo; + + return close(fd); +} +static ssize_t pack_xreadfn(long fd,void *buf,size_t count){ + int ret; + pack_bzinfo *bzinfo; + + bzinfo = pack_fdmap.find(fd)->second; + + bzinfo->bzs.next_out = (char*)buf; + bzinfo->bzs.avail_out = count; + while(bzinfo->endflag == false){ + if(bzinfo->len == 0){ + ret = read(fd,bzinfo->buf,PACK_BUFSIZE); + bzinfo->len = ret; + bzinfo->off = 0; + } + if(bzinfo->len == 0){ + break; + } + + bzinfo->bzs.next_in = bzinfo->buf + bzinfo->off; + bzinfo->bzs.avail_in = bzinfo->len; + while(bzinfo->bzs.avail_in > 0 && bzinfo->bzs.avail_out > 0){ + if(BZ2_bzDecompress(&bzinfo->bzs) != BZ_OK){ + bzinfo->endflag = true; + break; + } + } + bzinfo->off += bzinfo->len - bzinfo->bzs.avail_in; + bzinfo->len = bzinfo->bzs.avail_in; + + if(bzinfo->bzs.avail_out == 0){ + break; + } + } + + return count - bzinfo->bzs.avail_out; +} + +int pack_pack(char *packpath,char *dirpath){ + tartype_t tartype; + TAR *tarp; + + tartype.openfunc = pack_copenfn; + tartype.closefunc = pack_cclosefn; + tartype.readfunc = (readfunc_t)read; + tartype.writefunc = pack_cwritefn; + tar_open(&tarp,packpath,&tartype,O_WRONLY | O_CREAT,0644,TAR_GNU); + + tar_append_tree(tarp,dirpath,"."); + tar_close(tarp); + + return 0; +} +int pack_unpack(char *packpath,char *dirpath){ + tartype_t tartype; + TAR *tarp; + + tartype.openfunc = pack_xopenfn; + tartype.closefunc = pack_xclosefn; + tartype.readfunc = pack_xreadfn; + tartype.writefunc = (writefunc_t)write; + tar_open(&tarp,packpath,&tartype,O_RDONLY,0644,TAR_GNU); + + tar_extract_all(tarp,dirpath); + tar_close(tarp); + + return 0; +} diff --git a/toj/center/src/pack.h b/toj/center/src/pack.h new file mode 100644 index 0000000..8f8ac88 --- /dev/null +++ b/toj/center/src/pack.h @@ -0,0 +1,20 @@ +#define PACK_BUFSIZE 65536 +struct pack_bzinfo{ + bz_stream bzs; + char buf[PACK_BUFSIZE]; + int len; + int off; + bool endflag; +}; + +static int pack_copenfn(const char *pathname,int flags,...); +static int pack_cclosefn(long fd); +static ssize_t cpack_writefn(long fd,const void *buf,size_t count); +static int pack_xopenfn(const char *pathname,int flags,...); +static int pack_xclosefn(long fd); +static ssize_t xpack_readfn(long fd,void *buf,size_t count); + +static std::map pack_fdmap; + +int pack_pack(char *packpath,char *dirpath); +int pack_unpack(char *packpath,char *dirpath); diff --git a/toj/center/src/tpool.h b/toj/center/src/tpool.h new file mode 100644 index 0000000..08aedbc --- /dev/null +++ b/toj/center/src/tpool.h @@ -0,0 +1,169 @@ +class tpool_protofn{ +public: + virtual void operator()(void *data) = 0; +}; + +template +class tpool_fn : public tpool_protofn{ +private: + typedef void (C::*tpool_fn_type)(void *data); + C *obj; + tpool_fn_type fn; + +public: + tpool_fn(C *obj,tpool_fn_type fn){ + this->obj = obj; + this->fn = fn; + } + void operator()(void *data){ + (obj->*fn)(data); + } +}; +class tpool_static_fn : public tpool_protofn{ +private: + typedef void (*tpool_static_fn_type)(void *data); + tpool_static_fn_type fn; + +public: + tpool_static_fn(tpool_static_fn_type fn){ + this->fn = fn; + } + void operator()(void *data){ + fn(data); + } +}; + +class tpool_thcb{ +public: + tpool_protofn *th_fn; + void *th_data; + tpool_protofn *cb_fn; + void *cb_data; + + tpool_thcb(tpool_protofn *th_fn,void *th_data,tpool_protofn *cb_fn,void *cb_data){ + this->th_fn = th_fn; + this->th_data = th_data; + this->cb_fn = cb_fn; + this->cb_data = cb_data; + } + int run(){ + (*th_fn)(th_data); + return 0; + } + int done(){ + if(cb_fn != NULL){ + (*cb_fn)(cb_data); + } + return 0; + } +}; + +#define TPOOL_THREAD_MAXNUM 64 +class tpool{ +private: + std::queue wait_queue; + std::vector done_list; + pthread_t pt[TPOOL_THREAD_MAXNUM]; + int pt_num; + sem_t pt_sem; + pthread_mutex_t pt_mutex; + + static void* pt_runfn(void *arg){ + tpool *that; + tpool_thcb *thcb; + long long int sig; + + that = (tpool*)arg; + + while(true){ + + sem_wait(&that->pt_sem); + + pthread_mutex_lock(&that->pt_mutex); + + if(!that->wait_queue.empty()){ + thcb = that->wait_queue.front(); + that->wait_queue.pop(); + }else{ + thcb = NULL; + } + + pthread_mutex_unlock(&that->pt_mutex); + + if(thcb == NULL){ + continue; + } + + thcb->run(); + + pthread_mutex_lock(&that->pt_mutex); + + that->done_list.push_back(thcb); + + pthread_mutex_unlock(&that->pt_mutex); + + sig = 1; + write(that->fd,&sig,sizeof(sig)),that->done_list.size(); + } + return NULL; + } + +public: + int fd; + + tpool(int pt_num){ + if((this->pt_num = pt_num) > TPOOL_THREAD_MAXNUM){ + this->pt_num = TPOOL_THREAD_MAXNUM; + } + fd = eventfd(0,EFD_NONBLOCK); + sem_init(&pt_sem,0,0); + pthread_mutex_init(&pt_mutex,NULL); + } + ~tpool(){ + close(fd); + sem_destroy(&pt_sem); + pthread_mutex_destroy(&pt_mutex); + } + int start(){ + int i; + + for(i = 0;i < pt_num;i++){ + pthread_create(&pt[pt_num],NULL,pt_runfn,this); + } + + return 0; + } + int done(){ + int i; + std::vector l; + long long int sig; + + pthread_mutex_lock(&pt_mutex); + + l.swap(done_list); + + pthread_mutex_unlock(&pt_mutex); + + for(i = l.size() - 1;i >= 0;i--){ + l[i]->done(); + delete l[i]; + } + + read(fd,&sig,sizeof(sig)); + } + int add(tpool_protofn *th_fn,void *th_data,tpool_protofn *cb_fn,void *cb_data){ + tpool_thcb *thcb; + + thcb = new tpool_thcb(th_fn,th_data,cb_fn,cb_data); + + pthread_mutex_lock(&pt_mutex); + + wait_queue.push(thcb); + + pthread_mutex_unlock(&pt_mutex); + + sem_post(&pt_sem); + + return 0; + } +}; -- cgit v1.2.3