diff options
author | pzread <netfirewall@gmail.com> | 2012-12-10 21:06:41 +0800 |
---|---|---|
committer | pzread <netfirewall@gmail.com> | 2012-12-10 21:06:41 +0800 |
commit | 6342273bf29274f1fd7cac7c31fddf3cc1c7f05f (patch) | |
tree | e2714bec39880e1126b37c00e965176f33090e62 | |
parent | 1eb32c90ffc524b7d56eb0c64386c366848854b8 (diff) | |
download | taiwan-online-judge-lantw44-6342273bf29274f1fd7cac7c31fddf3cc1c7f05f.tar.gz taiwan-online-judge-lantw44-6342273bf29274f1fd7cac7c31fddf3cc1c7f05f.tar.zst taiwan-online-judge-lantw44-6342273bf29274f1fd7cac7c31fddf3cc1c7f05f.zip |
Add judge9 code(with debug code)
-rw-r--r-- | judge/check.c | 128 | ||||
-rw-r--r-- | judge/check_reactgrader.c | 571 | ||||
-rw-r--r-- | judge/judge_app.c | 13 | ||||
-rw-r--r-- | judge/judge_app.h | 3 | ||||
-rw-r--r-- | judge/judge_def.h | 15 | ||||
-rw-r--r-- | judge/judge_server.c | 292 | ||||
-rw-r--r-- | judge/judge_server.h | 30 | ||||
-rw-r--r-- | judge/judgm.h | 16 | ||||
-rw-r--r-- | judge/judgm_mod.c | 62 | ||||
-rw-r--r-- | judge/judgm_mod.h | 22 | ||||
-rw-r--r-- | judge/judgm_proc.c | 252 | ||||
-rw-r--r-- | judge/judgm_proc.h | 19 | ||||
-rw-r--r-- | judge/judgm_security.c | 2298 | ||||
-rw-r--r-- | judge/judgm_security.h | 154 | ||||
-rw-r--r-- | judge/judgm_syscall.c | 240 | ||||
-rw-r--r-- | judge/judgm_syscall.h | 70 | ||||
-rw-r--r-- | judge/judgm_syscall_asm.S | 54 | ||||
-rw-r--r-- | judge/judgx.h | 27 | ||||
-rw-r--r-- | judge/judgx_com.h | 19 | ||||
-rw-r--r-- | judge/judgx_lib.c | 287 | ||||
-rw-r--r-- | judge/judgx_lib.h | 13 | ||||
-rw-r--r-- | judge/judgx_line.h | 20 | ||||
-rw-r--r-- | judge/line.c | 195 | ||||
-rw-r--r-- | judge/line.h | 27 | ||||
-rw-r--r-- | judge/line_vscore.c | 189 | ||||
-rw-r--r-- | judge/line_vscore.h | 28 |
26 files changed, 5044 insertions, 0 deletions
diff --git a/judge/check.c b/judge/check.c new file mode 100644 index 0000000..bfe4a14 --- /dev/null +++ b/judge/check.c @@ -0,0 +1,128 @@ +#include<stdio.h> +#include<stdlib.h> +#include<limits.h> +#include<fcntl.h> +#include<signal.h> +#include<pthread.h> +#include<semaphore.h> +#include<termios.h> + +#include"judge_def.h" +#include"judgx.h" + +struct check_thread_info{ + int status; + sem_t *done_sem; +}; + +int mptd; +char ptname[PATH_MAX + 1]; +int infd; +int ansfd; + +DLL_PUBLIC int init(char *runpath,char *datapath){ + struct termios tes; + char tpath[PATH_MAX + 1]; + char newpath[PATH_MAX + 1]; + + printf("check1\n"); + + mptd = posix_openpt(O_RDWR); + grantpt(mptd); + unlockpt(mptd); + ptsname_r(mptd,ptname,sizeof(ptname)); + tcgetattr(mptd,&tes); + cfmakeraw(&tes); + tcsetattr(mptd,TCSANOW,&tes); + + snprintf(tpath,sizeof(tpath),"%s/in.txt",datapath); + snprintf(newpath,sizeof(newpath),"%s/in.txt",runpath); + if(link(tpath,newpath) == -1){ + unlink(newpath); + link(tpath,newpath); + } + infd = open(tpath,O_RDONLY); + snprintf(tpath,sizeof(tpath),"%s/ans.txt",datapath); + ansfd = open(tpath,O_RDONLY); + if(infd == -1 || ansfd == -1){ + goto error; + } + + printf("check2\n"); + + return 0; + +error: + + close(mptd); + close(infd); + close(ansfd); + + return -1; +} + +static void thread_clean(void *arg){ + close(mptd); + close(infd); + close(ansfd); + return; +} +DLL_PUBLIC void* thread(void *arg){ + int ret; + struct check_thread_info *thread_info; + + int flag; + char outbuf[4096]; + char ansbuf[4096]; + + pthread_cleanup_push(thread_clean,NULL); + thread_info = (struct check_thread_info*)arg; + + flag = 0; + while(1){ + if((ret = read(mptd,outbuf,4096)) <= 0){ + if(read(ansfd,ansbuf,1) > 0){ + flag = 1; + break; + }else{ + break; + } + } + if(read(ansfd,ansbuf,ret) != ret){ + flag = 1; + break; + } + if(memcmp(ansbuf,outbuf,ret) != 0){ + flag = 1; + break; + } + } + + if(flag == 0){ + thread_info->status = JUDGE_AC; + }else{ + thread_info->status = JUDGE_WA; + } + + pthread_cleanup_pop(thread_clean); + sem_post(thread_info->done_sem); + return NULL; +} +DLL_PUBLIC int stop(void){ + return 0; +} + +DLL_PUBLIC int run(){ + int sptd; + struct termios tes; + + sptd = open(ptname,O_RDWR); + tcgetattr(sptd,&tes); + cfmakeraw(&tes); + tcsetattr(sptd,TCSANOW,&tes); + + dup2(infd,0); + dup2(sptd,1); + dup2(sptd,2); + return 0; +} diff --git a/judge/check_reactgrader.c b/judge/check_reactgrader.c new file mode 100644 index 0000000..f283bc5 --- /dev/null +++ b/judge/check_reactgrader.c @@ -0,0 +1,571 @@ +#include<stdio.h> +#include<stdlib.h> +#include<limits.h> +#include<fcntl.h> +#include<signal.h> +#include<pthread.h> +#include<semaphore.h> +#include<termios.h> + +#include"judge_def.h" +#include"judgx.h" + +struct check_thread_info{ + int status; + int score; + int maxscore; + sem_t *done_sem; +}; + +int mptd; +char ptname[PATH_MAX + 1]; +int infd; + +// Opponent program for Guess that Cow +// Originally based on soln-opt by Hal Burch +// Extensive changes by Matt Craighead +#include <ctype.h> +#include <string.h> + +/* +guess.in: input case +standard input/output: student running program +stderr: grading output + */ + + +// Shared solver code for Guess that Cow +// Used by soln-mjc, opponent, and testgen +// Originally based on soln-opt by Hal Burch +// Extensive changes by Matt Craighead + +#define MAXPROP 8 +#define MAXVAL 3 +#define MAXITEM 50 +#define NAME "guess" + +#define HASHSIZE 904069 + +// Mask of cows. Would use a 64-bit int, but this is more portable and lets me +// optimize things the compiler would do a poor job at. +typedef struct { + unsigned int lo; + unsigned int hi; +} CowMask; + +typedef struct state { + CowMask member; + int score; + struct state *next; +} state_t; + +int item[MAXITEM][MAXPROP]; +int nitem, nprop; +int maxSearchDepth = 100; +int noHashTable; +CowMask maskhistory[200]; +char query[200][100]; +int resp[200]; +int nhist; + +int nQuestionsUsed, nOptimalQuestions; + +state_t *hashTable[HASHSIZE]; + +CowMask updateMasks[MAXPROP][1 << MAXVAL]; + +void FindBestQuestion(CowMask poss, int depth, int *question, int *score); + +CowMask BuildCowMask(int i) +{ + CowMask cm; + if (i < 32) { + cm.lo = 1 << i; + cm.hi = 0; + } else { + cm.lo = 0; + cm.hi = 1 << (i-32); + } + return cm; +} + +state_t *HashFind(CowMask poss, int depth) +{ + static state_t fakeHashEntry; + int h, temp; + state_t *lp; + + if (noHashTable) { + h = 0; + lp = &fakeHashEntry; + } else { + // Simple hash function + h = (poss.lo + poss.hi*7) % HASHSIZE; + + // Check hash table to see if this node has already been searched + for (lp = hashTable[h]; lp; lp = lp->next) { + if ((poss.lo == lp->member.lo) && (poss.hi == lp->member.hi)) { + return lp; + } + } + + // Alloc a hash entry and link it in + lp = (state_t *)malloc(sizeof(state_t)); + } + + // Recursively search to find score for this node + FindBestQuestion(poss, depth+1, &temp, &lp->score); + lp->member = poss; + if (!noHashTable) { + lp->next = hashTable[h]; + hashTable[h] = lp; + } + + return lp; +} + +void CleanHashTable(void) +{ + int i; + state_t *p, *next; + for (i = 0; i < HASHSIZE; i++) { + p = hashTable[i]; + while (p) { + next = p->next; + free(p); + p = next; + } + hashTable[i] = NULL; + } +} + +int CountBits(CowMask x) +{ + static int table[16] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4}; + int bits; + bits = 0; + while (x.lo) { + bits += table[x.lo & 0xF]; + x.lo >>= 4; + } + while (x.hi) { + bits += table[x.hi & 0xF]; + x.hi >>= 4; + } + return bits; +} + +void FindBestResponse(CowMask poss, int question, CowMask *newPoss, int *answer) +{ + int attr = question % MAXPROP; + int quest = question / MAXPROP; + int fcnt, tcnt, fquestions, tquestions; + CowMask fposs, tposs; + state_t *s; + int oldNoHashTable; + + oldNoHashTable = noHashTable; + noHashTable = 0; + + // Must choose answer of true or false, so run the + // solver on each case + fposs.lo = poss.lo & ~updateMasks[attr][quest].lo; + fposs.hi = poss.hi & ~updateMasks[attr][quest].hi; + tposs.lo = poss.lo & updateMasks[attr][quest].lo; + tposs.hi = poss.hi & updateMasks[attr][quest].hi; + fcnt = CountBits(fposs); + tcnt = CountBits(tposs); + if (fcnt <= 3) { + fquestions = fcnt-1; + } else { + s = HashFind(fposs, 0); fquestions = s->score; + } + if (tcnt <= 3) { + tquestions = tcnt-1; + } else { + s = HashFind(tposs, 0); tquestions = s->score; + } + + // First go by # of questions; if there's a tie, go by + // # of cows + if (fquestions > tquestions) { + *answer = 0; + } else if (fquestions < tquestions) { + *answer = 1; + } else if (fcnt > tcnt) { + *answer = 0; + } else if (fcnt < tcnt) { + *answer = 1; + } else { + // arbitrary + *answer = 0; + if (nitem == 4 && nQuestionsUsed == 2) *answer = 1; + } + + *newPoss = *answer ? tposs : fposs; + + noHashTable = oldNoHashTable; +} + +void FindBestQuestion(CowMask poss, int depth, int *question, int *score) +{ + CowMask fposs, tposs; + int lq, lp; + int bestScore, bestQuestion; + int tcnt, fcnt; + state_t *s; + + bestScore = 1000; + bestQuestion = -1; + + // Consider all properties to ask about + for (lp = 0; lp < nprop; lp++) { + // Consider all useful sets of values to ask about + // An empty list of values to ask about is useless + // Omit the last property so as to not repeat questions, because + // all questions can be phrased in two ways + for (lq = 1; lq < (1 << (MAXVAL-1)); lq++) { + // Get the sets of cows remaining after each answer + fposs.lo = poss.lo & ~updateMasks[lp][lq].lo; + fposs.hi = poss.hi & ~updateMasks[lp][lq].hi; + tposs.lo = poss.lo & updateMasks[lp][lq].lo; + tposs.hi = poss.hi & updateMasks[lp][lq].hi; + fcnt = CountBits(fposs); + tcnt = CountBits(tposs); + + // If one answer would leave no cows left, this question + // doesn't really give us any information + if ((fcnt == 0) || (tcnt == 0)) continue; + + // How many questions will be required after this one to + // solve the puzzle if we get an answer of "yes"? + if ((tcnt <= 3) || (depth >= maxSearchDepth)) { + // Small cases are easy + tcnt = tcnt - 1; + } else { + // Look in the hash table + s = HashFind(tposs, depth); + tcnt = s->score; + } + + // Quit early if no better than the best so far + if (tcnt >= bestScore) continue; + + // How many questions will be required after this one to + // solve the puzzle if we get an answer of "no"? + if ((fcnt <= 3) || (depth >= maxSearchDepth)) { + // Small cases are easy + fcnt = fcnt - 1; + } else { + // Look in the hash table + s = HashFind(fposs, depth); + fcnt = s->score; + } + + // Pick the worse of the two + if (tcnt < fcnt) tcnt = fcnt; + if (tcnt + 1 < bestScore) { + bestScore = tcnt + 1; + bestQuestion = lp + lq*MAXPROP; + } + } + } + + //assert(bestScore < 1000); + //assert(bestQuestion != -1); + + *question = bestQuestion; + *score = bestScore; +} + +void ParseInputFile(FILE *f) +{ + int lv, lv2; + char str[3]; + fscanf(f, "%d %d", &nitem, &nprop); + + for (lv = 0; lv < nitem; lv++) { + for (lv2 = 0; lv2 < nprop; lv2++) { + fscanf(f, "%s", str); + item[lv][lv2] = str[0] - 'X'; + } + } + +} + +void BuildUpdateMasks(void) +{ + int i, lp, lq; + + // Precompute sets of cows remaining after each possible question + for (lp = 0; lp < nprop; lp++) { + for (lq = 0; lq < (1 << MAXVAL); lq++) { + updateMasks[lp][lq].lo = 0; + updateMasks[lp][lq].hi = 0; + for (i = 0; i < nitem; i++) { + if (lq & (1 << item[i][lp])) { + CowMask cm = BuildCowMask(i); + updateMasks[lp][lq].lo |= cm.lo; + updateMasks[lp][lq].hi |= cm.hi; + } + } + } + } +} + +int judge(struct check_thread_info *thread_info){ + FILE *ioin; + FILE *ioout; + FILE *fin; + char line[256]; + int score, answer, quest, i; + CowMask poss; + + ioin = fdopen(mptd,"r"); + ioout = fdopen(mptd,"w"); + fin = fdopen(infd,"r"); + + CleanHashTable(); + ParseInputFile(fin); + BuildUpdateMasks(); + + // At first, all cows are possible + poss.lo = 0; + poss.hi = 0; + for (i = 0; i < nitem; i++) { + CowMask cm = BuildCowMask(i); + poss.lo |= cm.lo; + poss.hi |= cm.hi; + } + + nOptimalQuestions = 100; + + // Solve the problem to get the best possible score + FindBestQuestion(poss, 0, &quest, &nOptimalQuestions); + + nQuestionsUsed = 0; + maskhistory[nQuestionsUsed] = poss; + for (;;) { + if(fgets(line, sizeof(line), ioin) == NULL){ + return 1; + } + + if (line[strlen(line)-1] == '\n') line[strlen(line)-1] = 0; + if (line[0] == 'Q') { + int parsed, i, attr, val[3]; + + nQuestionsUsed++; + if(nQuestionsUsed > 100){ + fprintf(ioout, "ABORT\n"); + fprintf(stderr, "WRONG\nYour program asked more than 100 questions.\n"); + return 0; + } + if (!isdigit(line[2])) { + fprintf(stderr, "Wrong: unexpected input format: %s\n", line); + return 1; + } + attr = line[2] - '0'; + parsed = 0; i = 3; + while (line[i] != 0) { + if ((line[i] != ' ') || line[i+1] < 'X' || line[i+1] > 'Z') { + fprintf(stderr, "Wrong: unexpected input format: %s\n", line); + return 1; + } + val[parsed] = line[i+1]-'X'+1; + parsed++; + i += 2; + } + if (parsed < 1) { + fprintf(stderr, "Wrong: unexpected input format: %s\n", line); + return 1; + } + attr--; + quest = 0; + for (i = 0; i < parsed; i++) { + if ((val[i] < 1) || (val[i] > MAXVAL)) { + fprintf(stderr, "Incorrect: invalid attribute value in question\n"); + return 1; + } + quest |= 1 << (val[i]-1); + } + + FindBestResponse(poss, attr + quest*MAXPROP, &poss, &answer); + strcpy(query[nQuestionsUsed-1], line); + maskhistory[nQuestionsUsed-1] = poss; + resp[nQuestionsUsed-1] = answer; + + fprintf(ioout,"%d\n", answer); + fflush(ioout); + } else if (line[0] == 'C') { + // Done, check the answer + break; + } else { + fprintf(stderr, "Wrong: unexpected input format: %s\n", line); + return 1; + } + } + + if ((line[1] != ' ') || !isdigit(line[2])) { + fprintf(stderr, "Wrong: unexpected input format: %s", line); + return 1; + } + if (line[3] != 0) { + if (!isdigit(line[3]) || (line[4] != 0)) { + fprintf(stderr, "Wrong: unexpected input format: %s", line); + return 1; + } + } + sscanf(line, "C %d", &answer); + answer--; + + // To be correct, this cow must be the only remaining possible cow + if (CountBits(poss) != 1) { + fprintf(ioout, "ABORT\n"); + fprintf(stderr, "WRONG\n"); + fprintf(stderr, "The following cows are still consistent with the answers given:\n"); + fprintf(stderr, " "); + for(i=0; i<32; i++){ + if(poss.lo&(1<<i)){ + fprintf(stderr, " %d", i+1); + } + } + for(i=0;i<32; i++){ + if(poss.hi&(1<<i)){ + fprintf(stderr, " %d", i+32+1); + } + } + fprintf(stderr, "\n"); + return 0; + } else { + CowMask cm = BuildCowMask(answer); + if ((poss.lo != cm.lo) || (poss.hi != cm.hi)) { + for(i=0; i<nQuestionsUsed; i++){ + if(!(maskhistory[i].lo&cm.lo)&&!(maskhistory[i].hi&cm.hi)) + break; + } + fprintf(ioout, "ABORT\n"); + fprintf(stderr, "WRONG\nYour program claims the solution is cow %d,\n", answer+1); + fprintf(stderr, "but cow %d was eliminated by query #%d (%s) with response %d.\n", answer+1, i+1, query[i], resp[i]); + return 0; + } else { + if (nQuestionsUsed <= nOptimalQuestions) { + score = 10; + } else if (nQuestionsUsed == nOptimalQuestions+1) { + score = 8; + } else if (nQuestionsUsed == nOptimalQuestions+2) { + score = 5; + } else if (nQuestionsUsed <= nOptimalQuestions+5) { + score = 4; + } else { + score = 3; + } + if (score < 10) { + fprintf(stderr, "OK %d\n", score); + } else { + fprintf(stderr, "OK\n"); + } + if(nQuestionsUsed < nOptimalQuestions){ + fprintf(stderr, "Student is better than us.\n"); + } + + thread_info->score = score; + if(nQuestionsUsed < nOptimalQuestions){ + thread_info->score += (nOptimalQuestions - nQuestionsUsed); + } + } + } + + fprintf(ioout, "DONE\n"); + + if(thread_info->score > 10){ + thread_info->maxscore = thread_info->score; + }else{ + thread_info->maxscore = 10; + } + + if(thread_info->score == thread_info->maxscore){ + thread_info->status = JUDGE_AC; + }else{ + thread_info->status = JUDGE_WA; + } + + return 0; +} + +DLL_PUBLIC int init(char *runpath,char *datapath){ + struct termios tes; + char tpath[PATH_MAX + 1]; + char newpath[PATH_MAX + 1]; + + mptd = posix_openpt(O_RDWR); + grantpt(mptd); + unlockpt(mptd); + ptsname_r(mptd,ptname,sizeof(ptname)); + tcgetattr(mptd,&tes); + cfmakeraw(&tes); + tcsetattr(mptd,TCSANOW,&tes); + + printf("check1\n"); + + snprintf(tpath,sizeof(tpath),"%s/in.txt",datapath); + snprintf(newpath,sizeof(newpath),"%s/guess.in",runpath); + if(link(tpath,newpath) == -1){ + unlink(newpath); + link(tpath,newpath); + } + infd = open(tpath,O_RDONLY); + if(infd == -1){ + goto error; + } + + printf("check2\n"); + + return 0; + +error: + + close(mptd); + close(infd); + + return -1; +} + +static void thread_clean(void *arg){ + close(mptd); + close(infd); + return; +} +DLL_PUBLIC void* thread(void *arg){ + struct check_thread_info *thread_info; + + pthread_cleanup_push(thread_clean,NULL); + thread_info = (struct check_thread_info*)arg; + + thread_info->status = JUDGE_WA; + thread_info->score = 0; + thread_info->maxscore = 10; + + judge(thread_info); + + pthread_cleanup_pop(thread_clean); + sem_post(thread_info->done_sem); + return NULL; +} +DLL_PUBLIC int stop(void){ + return 0; +} + +DLL_PUBLIC int run(){ + int sptd; + struct termios tes; + + sptd = open(ptname,O_RDWR); + tcgetattr(sptd,&tes); + cfmakeraw(&tes); + tcsetattr(sptd,TCSANOW,&tes); + + dup2(sptd,0); + dup2(sptd,1); + dup2(sptd,2); + return 0; +} diff --git a/judge/judge_app.c b/judge/judge_app.c new file mode 100644 index 0000000..f891602 --- /dev/null +++ b/judge/judge_app.c @@ -0,0 +1,13 @@ +#include<stdio.h> +#include<stdlib.h> +#include<signal.h> + +#include"judge_app.h" + +int main(int argc,char *argv[]){ + + signal(SIGPIPE,SIG_IGN); + judge_server(); + + return 0; +} diff --git a/judge/judge_app.h b/judge/judge_app.h new file mode 100644 index 0000000..fdb8812 --- /dev/null +++ b/judge/judge_app.h @@ -0,0 +1,3 @@ +int judge_modfd; + +extern int judge_server(); diff --git a/judge/judge_def.h b/judge/judge_def.h new file mode 100644 index 0000000..b55c8d4 --- /dev/null +++ b/judge/judge_def.h @@ -0,0 +1,15 @@ +#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_DB_STATUSMAX 1024 +#define JUDGE_DB_SCOREMAX 1024 +#define JUDGE_DB_MAXSCOREMAX 1024 +#define JUDGE_DB_RUNTIMEMAX 1024 +#define JUDGE_DB_PEAKMEMMAX 1024 diff --git a/judge/judge_server.c b/judge/judge_server.c new file mode 100644 index 0000000..f0e48cd --- /dev/null +++ b/judge/judge_server.c @@ -0,0 +1,292 @@ +#define _XOPEN_SOURCE 600 +#define _GNU_SOURCE + +#include<stdio.h> +#include<stdlib.h> +#include<string.h> +#include<limits.h> +#include<pthread.h> +#include<semaphore.h> +#include<dlfcn.h> +#include<sys/socket.h> +#include<sys/mman.h> +#include<netinet/in.h> +#include<errno.h> +#include<ftw.h> +#include<libpq-fe.h> + +#include"judge_def.h" +#include"judgx_line.h" +#include"judge_server.h" + +#define JUDGE_DB_MAXSCOREMAX 1024 + +static int server_cleardir_callback(const char *path,const struct stat *st,int flag,struct FTW *ftwbuf){ + if(ftwbuf->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_updatedb(PGconn *sqlc,int submitid,int result_count,struct judgx_line_result *result){ + int i; + int j; + + char sqlstatus[JUDGE_DB_STATUSMAX + 1]; + char sqlscore[JUDGE_DB_SCOREMAX + 1]; + char sqlmaxscore[JUDGE_DB_MAXSCOREMAX + 1]; + char sqlruntime[JUDGE_DB_RUNTIMEMAX + 1]; + char sqlpeakmem[JUDGE_DB_PEAKMEMMAX + 1]; + char sqlsubmitid[64]; + + const char *sqlparam[6]; + PGresult *sqlr; + + printf("sql1 %d\n",getpid()); + + sqlstatus[0] = '{'; + for(i = 0,j = 1;i < result_count;i++){ + snprintf(sqlstatus + j,sizeof(sqlstatus) - j,"%d,",result[i].status); + while(sqlstatus[j] != '\0'){ + j++; + } + } + sqlstatus[j - 1] = '}'; + + sqlscore[0] = '{'; + for(i = 0,j = 1;i < result_count;i++){ + snprintf(sqlscore + j,sizeof(sqlscore) - j,"%d,",result[i].score); + while(sqlscore[j] != '\0'){ + j++; + } + } + sqlscore[j - 1] = '}'; + + sqlmaxscore[0] = '{'; + for(i = 0,j = 1;i < result_count;i++){ + snprintf(sqlmaxscore + j,sizeof(sqlmaxscore) - j,"%d,",result[i].maxscore); + while(sqlmaxscore[j] != '\0'){ + j++; + } + } + sqlmaxscore[j - 1] = '}'; + + sqlruntime[0] = '{'; + for(i = 0,j = 1;i < result_count;i++){ + snprintf(sqlruntime + j,sizeof(sqlruntime) - j,"%lu,",result[i].runtime); + while(sqlruntime[j] != '\0'){ + j++; + } + } + sqlruntime[j - 1] = '}'; + + sqlpeakmem[0] = '{'; + for(i = 0,j = 1;i < result_count;i++){ + snprintf(sqlpeakmem + j,sizeof(sqlpeakmem) - j,"%lu,",result[i].peakmem); + while(sqlpeakmem[j] != '\0'){ + j++; + } + } + sqlpeakmem[j - 1] = '}'; + + snprintf(sqlsubmitid,64,"%d",submitid); + + printf("sql2\n"); + + sqlparam[0] = sqlstatus; + sqlparam[1] = sqlscore; + sqlparam[2] = sqlmaxscore; + sqlparam[3] = sqlruntime; + sqlparam[4] = sqlpeakmem; + sqlparam[5] = sqlsubmitid; + + sqlr = PQexecParams(sqlc, + "UPDATE \"submit\" SET \"status\"=$1,\"score\"=$2,\"maxscore\"=$3,\"runtime\"=$4,\"peakmem\"=$5 WHERE \"submitid\"=$6;", + 6, + NULL, + sqlparam, + NULL, + NULL, + 0); + PQclear(sqlr); + + printf("sql3\n"); + + return 0; +} +static void* server_thread(void *arg){ + int i; + + struct server_thread_info *thread_info; + struct judge_submit_info *submit_info; + struct judgx_line_info *line_info; + + PGconn *sqlc; + char tname[NAME_MAX + 1]; + char tpath[PATH_MAX + 1]; + line_run_fn line_run; + int runpid; + + thread_info = (struct server_thread_info*)arg; + + sqlc = PQconnectdb("host=localhost port=5432 dbname=expoj user=expoj password=xxxxx"); + + while(1){ + printf("in\n"); + + sem_wait(&server_queue_sem); + + pthread_mutex_lock(&server_queue_mutex); + + printf("in1\n"); + + submit_info = server_queue_head.next; + server_queue_head.next = submit_info->next; + submit_info->next->prev = &server_queue_head; + + pthread_mutex_unlock(&server_queue_mutex); + + printf("in2\n"); + + server_cleardir(thread_info->run_path); + + printf("in3\n"); + + line_info = mmap(NULL,sizeof(struct judgx_line_info),PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS,-1,0); + snprintf(line_info->pro_path,sizeof(line_info->pro_path),"pro/%d",submit_info->proid); + snprintf(line_info->cpp_path,sizeof(line_info->cpp_path),"submit/%d_submit.cpp",submit_info->submitid); + line_info->run_path[0] = '\0'; + strncat(line_info->run_path,thread_info->run_path,sizeof(line_info->run_path)); + + printf("in4"); + + snprintf(tpath,sizeof(tpath),"pro/%d/%d_setting.txt",submit_info->proid,submit_info->proid); + line_info->set_file = fopen(tpath,"r"); + + printf("in5\n"); + + fgets(tname,sizeof(tname),line_info->set_file); + tname[strlen(tname) - 1] = '\0'; + snprintf(tpath,sizeof(tpath),"judge/%s.so",tname); + + printf("in5-1\n"); + + line_info->line_dll = dlopen(tpath,RTLD_LAZY | RTLD_NODELETE); + + printf("in5-2\n"); + + fgets(tname,sizeof(tname),line_info->set_file); + tname[strlen(tname) - 1] = '\0'; + snprintf(tpath,sizeof(tpath),"judge/%s.so",tname); + + printf("in5-3\n"); + + line_info->check_dll = dlopen(tpath,RTLD_LAZY | RTLD_NODELETE); + + printf("in6\n"); + + line_run = dlsym(line_info->line_dll,"run"); + if((runpid = fork()) == 0){ + line_run(line_info); + exit(0); + } + waitpid(runpid,NULL,0); + + printf("in7\n"); + + server_updatedb(sqlc,submit_info->submitid,line_info->result_count,line_info->result); + + printf("in8\n"); + + fclose(line_info->set_file); + dlclose(line_info->line_dll); + dlclose(line_info->check_dll); + + munmap(line_info,sizeof(struct judgx_line_info)); + free(submit_info); + + printf("out\n"); + } + + PQfinish(sqlc); + + return NULL; +} +int judge_server(){ + int ret; + int i; + + struct server_thread_info *thread_info; + + int ssd; + struct sockaddr_in saddr; + struct sockaddr_in caddr; + int csd; + char *buf; + int submitid; + int proid; + struct judge_submit_info *submit_info; + + server_queue_head.next = &server_queue_head; + server_queue_head.prev = &server_queue_head; + sem_init(&server_queue_sem,0,0); + pthread_mutex_init(&server_queue_mutex,NULL); + + thread_info = (struct server_thread_info*)malloc(sizeof(struct server_thread_info) * 4); + for(i = 0;i < 2;i++){ + thread_info[i].threadid = i; + snprintf(thread_info[i].run_path,sizeof(thread_info[i].run_path),"run/%d",i); + mkdir(thread_info[i].run_path,0775); + pthread_create(&thread_info[i].pt,NULL,server_thread,&thread_info[i]); + } + + ssd = socket(AF_INET,SOCK_STREAM,0); + saddr.sin_family = AF_INET; + saddr.sin_port = htons(2501); + saddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + bind(ssd,(struct sockaddr*)&saddr,sizeof(saddr)); + listen(ssd,128); + + buf = malloc(65536); + while((csd = accept(ssd,(struct sockaddr*)&saddr,&ret)) != -1){ + i = 0; + if((ret = recv(csd,buf + i,65536,0)) != -1){ + i += ret; + } + sscanf(buf,"%d %d",&submitid,&proid); + + printf(" %d %d\n",submitid,proid); + + submit_info = malloc(sizeof(struct judge_submit_info)); + submit_info->submitid = submitid; + submit_info->proid = proid; + + pthread_mutex_lock(&server_queue_mutex); + + submit_info->next = &server_queue_head; + submit_info->prev = server_queue_head.prev; + server_queue_head.prev->next = submit_info; + server_queue_head.prev = submit_info; + + pthread_mutex_unlock(&server_queue_mutex); + + sem_post(&server_queue_sem); + + close(csd); + } + free(buf); + + free(thread_info); + + return 0; +} + diff --git a/judge/judge_server.h b/judge/judge_server.h new file mode 100644 index 0000000..9d7b753 --- /dev/null +++ b/judge/judge_server.h @@ -0,0 +1,30 @@ +typedef int (*line_run_fn)(struct judgx_line_info *line_info);
+
+struct server_thread_info{
+ int threadid;
+ pthread_t pt;
+
+ char run_path[PATH_MAX + 1];
+};
+struct judge_submit_info{
+ struct judge_submit_info *next;
+ struct judge_submit_info *prev;
+
+ int submitid;
+ int proid;
+};
+
+static int server_cleardir_callback(const char *path,const struct stat *st,int flag,struct FTW *ftwbuf);
+static int server_cleardir(char *path);
+static int server_updatedb(PGconn *sqlc,int submitid,int result_count,struct judgx_line_result *result);
+static void* server_thread(void *arg);
+
+static struct judge_submit_info server_queue_head;
+static sem_t server_queue_sem;
+static pthread_mutex_t server_queue_mutex;
+
+int judge_server();
+
+extern struct judge_proc_info* judge_proc_create(char *abspath,char *path,char *sopath,unsigned long timelimit,unsigned long memlimit);
+extern int judge_proc_free(struct judge_proc_info *proc_info);
+extern int judge_proc_run(struct judge_proc_info *proc_info);
diff --git a/judge/judgm.h b/judge/judgm.h new file mode 100644 index 0000000..f2c0841 --- /dev/null +++ b/judge/judgm.h @@ -0,0 +1,16 @@ +struct judgm_proc_info{ + struct hlist_node node; + struct list_head list; + + struct task_struct *task; + struct file *pin; + struct file *pout; + char run_path[PATH_MAX + 1]; + int status; + unsigned long timelimit; + unsigned long jiffiesstart; + unsigned long jiffiesend; + unsigned long memlimit; + unsigned long runtime; + unsigned long peakmem; +}; diff --git a/judge/judgm_mod.c b/judge/judgm_mod.c new file mode 100644 index 0000000..092902a --- /dev/null +++ b/judge/judgm_mod.c @@ -0,0 +1,62 @@ +#include<linux/module.h> +#include<linux/kernel.h> +#include<linux/kdev_t.h> +#include<linux/device.h> +#include<linux/cdev.h> +#include<linux/fs.h> + +#include"judgm_mod.h" +#include"judgm.h" +#include"judgx_com.h" + +static int __init mod_init(){ + alloc_chrdev_region(&mod_dev,0,1,"judgm"); + mod_class = class_create(THIS_MODULE,"chardev"); + device_create(mod_class,NULL,mod_dev,NULL,"judgm"); + cdev_init(&mod_cdev,&mod_fops); + cdev_add(&mod_cdev,mod_dev,1); + + judgm_proc_init(); + judgm_security_hook(); + judgm_syscall_hook(); + + pr_alert("judgm: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); + + judgm_proc_exit(); + judgm_syscall_unhook(); + judgm_security_unhook(); + + pr_alert("judgm:Exit\n"); +} +module_init(mod_init); +module_exit(mod_exit); +MODULE_LICENSE("GPL"); + +static long mod_ioctl(struct file *file,unsigned int cmd,unsigned long arg){ + int ret; + + ret = -1; + switch(cmd){ + case IOCTL_PROC_ADD: + ret = judgm_proc_add(arg); + break; + case IOCTL_PROC_GET: + ret = judgm_proc_get(arg); + break; + case IOCTL_PROC_KILL: + ret = judgm_proc_kill(arg); + break; + case IOCTL_PROC_DEL: + ret = judgm_proc_del(arg); + break; + } + + return ret; +} diff --git a/judge/judgm_mod.h b/judge/judgm_mod.h new file mode 100644 index 0000000..5d7f509 --- /dev/null +++ b/judge/judgm_mod.h @@ -0,0 +1,22 @@ +static int __init mod_init(void); +static void __exit mod_exit(void); +static long mod_ioctl(struct file *file,unsigned int cmd,unsigned long arg); + +static dev_t mod_dev; +static struct cdev mod_cdev; +static struct class *mod_class; +static struct file_operations mod_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = mod_ioctl +}; + +extern int judgm_proc_init(void); +extern int judgm_proc_exit(void); +extern int judgm_proc_add(unsigned long arg); +extern int judgm_proc_get(unsigned long arg); +extern int judgm_proc_kill(unsigned long arg); +extern int judgm_proc_del(unsigned long arg); +extern int judgm_syscall_hook(void); +extern int judgm_syscall_unhook(void); +extern int judgm_security_hook(void); +extern int judgm_security_unhook(void); diff --git a/judge/judgm_proc.c b/judge/judgm_proc.c new file mode 100644 index 0000000..2933512 --- /dev/null +++ b/judge/judgm_proc.c @@ -0,0 +1,252 @@ +#include<linux/fs.h> +#include<linux/slab.h> +#include<linux/fdtable.h> +#include<linux/sched.h> +#include<linux/kthread.h> +#include<asm/uaccess.h> + +#include"judgm.h" +#include"judge_def.h" +#include"judgx_com.h" +#include"judgm_proc.h" + +int judgm_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 judgm_proc_info),0,0,NULL); + + proc_watcher_task = kthread_run(proc_watcher,NULL,"judgm_proc"); + + return 0; +} + +int judgm_proc_add(unsigned long arg){ + int ret; + + struct task_struct *task; + struct judgm_proc_info *info; + struct judgx_com_proc_add *com_proc_add; + + ret = 0; + + com_proc_add = kmalloc(sizeof(struct judgx_com_proc_add),GFP_KERNEL); + copy_from_user(com_proc_add,(void* __user)arg,sizeof(struct judgx_com_proc_add)); + + if((task = get_pid_task(find_vpid(com_proc_add->pid),PIDTYPE_PID)) == NULL){ + ret = -1; + goto end; + } + if(judgm_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->pin = fcheck_files(task->files,0); + info->pout = fcheck_files(task->files,1); + info->status = JUDGE_AC; + info->timelimit = com_proc_add->timelimit; + info->jiffiesstart = jiffies; + info->jiffiesend = info->jiffiesstart + usecs_to_jiffies(com_proc_add->hardtimelimit); + info->memlimit = com_proc_add->memlimit; + info->runtime = 0L; + info->peakmem = 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->task = (unsigned long)task; + copy_to_user((void* __user)arg,com_proc_add,sizeof(struct judgx_com_proc_add)); + +end: + + kfree(com_proc_add); + + return ret; +} +int judgm_proc_get(unsigned long arg){ + struct task_struct *task; + struct judgm_proc_info *info; + struct judgx_com_proc_get *com_proc_get; + + com_proc_get = kmalloc(sizeof(struct judgx_com_proc_get),GFP_KERNEL); + copy_from_user(com_proc_get,(void* __user)arg,sizeof(struct judgx_com_proc_get)); + task = (struct task_struct*)com_proc_get->task; + if((info = judgm_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->peakmem = info->peakmem; + + copy_to_user((void* __user)arg,com_proc_get,sizeof(struct judgx_com_proc_get)); + kfree(com_proc_get); + + return 0; +} +int judgm_proc_kill(unsigned long arg){ + struct task_struct *task; + struct judgm_proc_info *info; + + task = (struct task_struct*)arg; + if((info = judgm_proc_task_lookup(task)) == NULL){ + return -1; + } + + if(send_sig(SIGKILL,task,0)){ + return -1; + } + return 0; +} +int judgm_proc_del(unsigned long arg){ + struct task_struct *task; + struct judgm_proc_info *info; + + task = (struct task_struct*)arg; + if((info = judgm_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 judgm_proc_info* judgm_proc_task_lookup(struct task_struct *task){ + struct judgm_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; +} +int judgm_proc_exit(){ + kthread_stop(proc_watcher_task); + return 0; +} +static int proc_watcher(void *data){ + struct judgm_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){ + info->status = JUDGE_TLE; + send_sig(SIGKILL,info->task,0); + }else if(time_after(jiffies,info->jiffiesend)){ + info->runtime = jiffies_to_usecs((unsigned long)(-((long)info->jiffiesstart - (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; +} +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); + fd = 3; + 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_close_on_exec(fd,fdt); + __clear_open_fd(fd,fdt); + 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/judge/judgm_proc.h b/judge/judgm_proc.h new file mode 100644 index 0000000..9ccc032 --- /dev/null +++ b/judge/judgm_proc.h @@ -0,0 +1,19 @@ +#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 judgm_proc_init(void); +int judgm_proc_exit(void); +int judgm_proc_add(unsigned long arg); +int judgm_proc_get(unsigned long arg); +int judgm_proc_kill(unsigned long arg); +int judgm_proc_del(unsigned long arg); +struct judgm_proc_info* judgm_proc_task_lookup(struct task_struct *task); diff --git a/judge/judgm_security.c b/judge/judgm_security.c new file mode 100644 index 0000000..a8ed14e --- /dev/null +++ b/judge/judgm_security.c @@ -0,0 +1,2298 @@ +#include<linux/fs.h> +#include<linux/security.h> +#include<linux/sched.h> +#include<asm/uaccess.h> + +#include"judge_def.h" +#include"judgm.h" +#include"judgx_com.h" +#include"judgm_security.h" + +int judgm_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.sb_alloc_security = hook_sb_alloc_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_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_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_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.file_permission = hook_file_permission; + //hook_sops.file_alloc_security = hook_file_alloc_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.cred_alloc_blank = hook_cred_alloc_blank; + //hook_sops.cred_prepare = hook_cred_prepare; + 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_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.ipc_permission = hook_ipc_permission; + hook_sops.msg_msg_alloc_security = hook_msg_msg_alloc_security; + hook_sops.msg_queue_alloc_security = hook_msg_queue_alloc_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_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_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.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.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.inet_conn_request = hook_inet_conn_request; + hook_sops.secmark_relabel_packet = hook_secmark_relabel_packet; + hook_sops.tun_dev_create = hook_tun_dev_create; + hook_sops.tun_dev_attach = hook_tun_dev_attach; + hook_sops.key_alloc = hook_key_alloc; + 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; + + *security_hook_addr = (unsigned long)&hook_sops; + + return 0; +} +int judgm_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)*(u32*)addr + 8UL); +} + +static int hook_inode_permission(struct inode *inode,int mask){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->inode_permission(inode,mask); + } + + pr_alert("judgm:PID %d inode_permission %08x\n",current->tgid,mask); + + if((mask & ~(MAY_EXEC | MAY_READ | MAY_OPEN | MAY_CHDIR | MAY_NOT_BLOCK)) != 0){ + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; + } + return ori_sops->inode_permission(inode,mask); +} +static int hook_file_open(struct file *file, const struct cred *cred){ + int ret; + int i; + + struct judgm_proc_info *info; + char *buf_path,*path; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + 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); + + pr_alert("judgm:PID %d file_open %s %08x\n",current->tgid,path,file->f_mode); + + 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){ + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return ret; + } + return ori_sops->file_open(file,cred); +} +static int hook_file_permission(struct file *file,int mask){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->file_permission(file,mask); + } + + /*buf_path = kmalloc(sizeof(char) * (PATH_MAX + 1),GFP_KERNEL); + path = d_path(&file->f_path,buf_path,PATH_MAX + 1); + + pr_alert("judgm:PID %d file_permission %s %08x\n",current->tgid,path,mask); + + kfree(buf_path);*/ + + if((mask & ~(MAY_READ | MAY_WRITE)) != 0){ + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; + }else if((mask & MAY_WRITE) != 0 && file != info->pout){ + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; + } + return ori_sops->file_permission(file,mask); +} +static int hook_vm_enough_memory(struct mm_struct *mm,long pages){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->vm_enough_memory(mm,pages); + } + + info->peakmem = (mm->total_vm + pages) << PAGE_SHIFT; + pr_alert("judgm:PID %d vm_enough_memory %lu\n",current->tgid,info->peakmem); + + if(info->peakmem > 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 judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->ptrace_access_check(child,mode); + } + + pr_alert("judgm:PID %d ptrace_access_check\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_ptrace_traceme(struct task_struct *parent){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->ptrace_traceme(parent); + } + + pr_alert("judgm:PID %d ptrace_traceme\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_capget(struct task_struct *target,kernel_cap_t *effective,kernel_cap_t *inheritable,kernel_cap_t *permitted){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->capget(target,effective,inheritable,permitted); + } + + pr_alert("judgm:PID %d capget\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + 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 judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->capset(new,old,effective,inheritable,permitted); + } + + pr_alert("judgm:PID %d capset\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +/*static int hook_capable(const struct cred *cred,struct user_namespace *ns,int cap,int audit){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->capable(cred,ns,cap,audit); + } + + pr_alert("judgm:PID %d capable\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; + }*/ +static int hook_quotactl(int cmds,int type,int id,struct super_block *sb){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->quotactl(cmds,type,id,sb); + } + + pr_alert("judgm:PID %d quotactl\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_quota_on(struct dentry *dentry){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->quota_on(dentry); + } + + pr_alert("judgm:PID %d quota_on\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_syslog(int type){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->syslog(type); + } + + pr_alert("judgm:PID %d syslog\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_settime(const struct timespec *ts,const struct timezone *tz){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->settime(ts,tz); + } + + pr_alert("judgm:PID %d settime\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +/*static int hook_bprm_set_creds(struct linux_binprm *bprm){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->bprm_set_creds(bprm); + } + + pr_alert("judgm:PID %d bprm_set_creds\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; + }*/ +/*static int hook_bprm_check_security(struct linux_binprm *bprm){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->bprm_check_security(bprm); + } + + pr_alert("judgm:PID %d bprm_check_security\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; + }*/ +/*static int hook_bprm_secureexec(struct linux_binprm *bprm){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->bprm_secureexec(bprm); + } + + pr_alert("judgm:PID %d bprm_secureexec\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; + }*/ +static int hook_sb_alloc_security(struct super_block *sb){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->sb_alloc_security(sb); + } + + pr_alert("judgm:PID %d sb_alloc_security\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_sb_copy_data(char *orig,char *copy){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->sb_copy_data(orig,copy); + } + + pr_alert("judgm:PID %d sb_copy_data\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_sb_remount(struct super_block *sb,void *data){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->sb_remount(sb,data); + } + + pr_alert("judgm:PID %d sb_remount\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_sb_kern_mount(struct super_block *sb,int flags,void *data){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->sb_kern_mount(sb,flags,data); + } + + pr_alert("judgm:PID %d sb_kern_mount\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_sb_show_options(struct seq_file *m,struct super_block *sb){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->sb_show_options(m,sb); + } + + pr_alert("judgm:PID %d sb_show_options\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_sb_statfs(struct dentry *dentry){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->sb_statfs(dentry); + } + + pr_alert("judgm:PID %d sb_statfs\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_sb_mount(char *dev_name,struct path *path,char *type,unsigned long flags,void *data){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->sb_mount(dev_name,path,type,flags,data); + } + + pr_alert("judgm:PID %d sb_mount\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_sb_umount(struct vfsmount *mnt,int flags){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->sb_umount(mnt,flags); + } + + pr_alert("judgm:PID %d sb_umount\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_sb_pivotroot(struct path *old_path,struct path *new_path){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->sb_pivotroot(old_path,new_path); + } + + pr_alert("judgm:PID %d sb_pivotroot\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_sb_set_mnt_opts(struct super_block *sb,struct security_mnt_opts *opts){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->sb_set_mnt_opts(sb,opts); + } + + pr_alert("judgm:PID %d sb_set_mnt_opts\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_sb_parse_opts_str(char *options,struct security_mnt_opts *opts){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->sb_parse_opts_str(options,opts); + } + + pr_alert("judgm:PID %d sb_parse_opts_str\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_path_unlink(struct path *dir,struct dentry *dentry){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->path_unlink(dir,dentry); + } + + pr_alert("judgm:PID %d path_unlink\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_path_mkdir(struct path *dir,struct dentry *dentry,umode_t mode){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->path_mkdir(dir,dentry,mode); + } + + pr_alert("judgm:PID %d path_mkdir\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_path_rmdir(struct path *dir,struct dentry *dentry){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->path_rmdir(dir,dentry); + } + + pr_alert("judgm:PID %d path_rmdir\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_path_mknod(struct path *dir,struct dentry *dentry,umode_t mode,unsigned int dev){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->path_mknod(dir,dentry,mode,dev); + } + + pr_alert("judgm:PID %d path_mknod\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_path_truncate(struct path *path){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->path_truncate(path); + } + + pr_alert("judgm:PID %d path_truncate\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_path_symlink(struct path *dir,struct dentry *dentry,const char *old_name){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->path_symlink(dir,dentry,old_name); + } + + pr_alert("judgm:PID %d path_symlink\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_path_link(struct dentry *old_dentry,struct path *new_dir,struct dentry *new_dentry){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->path_link(old_dentry,new_dir,new_dentry); + } + + pr_alert("judgm:PID %d path_link\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_path_rename(struct path *old_dir,struct dentry *old_dentry,struct path *new_dir,struct dentry *new_dentry){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->path_rename(old_dir,old_dentry,new_dir,new_dentry); + } + + pr_alert("judgm:PID %d path_rename\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_path_chmod(struct path *path,umode_t mode){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->path_chmod(path,mode); + } + + pr_alert("judgm:PID %d path_chmod\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_path_chown(struct path *path,uid_t uid,gid_t gid){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->path_chown(path,uid,gid); + } + + pr_alert("judgm:PID %d path_chown\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_path_chroot(struct path *path){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->path_chroot(path); + } + + pr_alert("judgm:PID %d path_chroot\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +/*static int hook_inode_alloc_security(struct inode *inode){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->inode_alloc_security(inode); + } + + pr_alert("judgm:PID %d inode_alloc_security\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; + }*/ +static int hook_inode_init_security(struct inode *inode,struct inode *dir,const struct qstr *qstr,char **name,void **value,size_t *len){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->inode_init_security(inode,dir,qstr,name,value,len); + } + + pr_alert("judgm:PID %d inode_init_security\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_inode_create(struct inode *dir,struct dentry *dentry,umode_t mode){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->inode_create(dir,dentry,mode); + } + + pr_alert("judgm:PID %d inode_create\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_inode_link(struct dentry *old_dentry,struct inode *dir,struct dentry *new_dentry){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->inode_link(old_dentry,dir,new_dentry); + } + + pr_alert("judgm:PID %d inode_link\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_inode_unlink(struct inode *dir,struct dentry *dentry){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->inode_unlink(dir,dentry); + } + + pr_alert("judgm:PID %d inode_unlink\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_inode_symlink(struct inode *dir,struct dentry *dentry,const char *old_name){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->inode_symlink(dir,dentry,old_name); + } + + pr_alert("judgm:PID %d inode_symlink\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_inode_mkdir(struct inode *dir,struct dentry *dentry,umode_t mode){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->inode_mkdir(dir,dentry,mode); + } + + pr_alert("judgm:PID %d inode_mkdir\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_inode_rmdir(struct inode *dir,struct dentry *dentry){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->inode_rmdir(dir,dentry); + } + + pr_alert("judgm:PID %d inode_rmdir\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_inode_mknod(struct inode *dir,struct dentry *dentry,umode_t mode,dev_t dev){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->inode_mknod(dir,dentry,mode,dev); + } + + pr_alert("judgm:PID %d inode_mknod\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_inode_rename(struct inode *old_dir,struct dentry *old_dentry,struct inode *new_dir,struct dentry *new_dentry){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->inode_rename(old_dir,old_dentry,new_dir,new_dentry); + } + + pr_alert("judgm:PID %d inode_rename\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_inode_readlink(struct dentry *dentry){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->inode_readlink(dentry); + } + + pr_alert("judgm:PID %d inode_readlink\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +/*static int hook_inode_follow_link(struct dentry *dentry,struct nameidata *nd){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->inode_follow_link(dentry,nd); + } + + pr_alert("judgm:PID %d inode_follow_link\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; + }*/ +static int hook_inode_setattr(struct dentry *dentry,struct iattr *attr){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->inode_setattr(dentry,attr); + } + + pr_alert("judgm:PID %d inode_setattr\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +/*static int hook_inode_getattr(struct vfsmount *mnt,struct dentry *dentry){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->inode_getattr(mnt,dentry); + } + + pr_alert("judgm:PID %d inode_getattr\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; + }*/ +static int hook_inode_setxattr(struct dentry *dentry,const char *name,const void *value,size_t size,int flags){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->inode_setxattr(dentry,name,value,size,flags); + } + + pr_alert("judgm:PID %d inode_setxattr\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_inode_getxattr(struct dentry *dentry,const char *name){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->inode_getxattr(dentry,name); + } + + pr_alert("judgm:PID %d inode_getxattr\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_inode_listxattr(struct dentry *dentry){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->inode_listxattr(dentry); + } + + pr_alert("judgm:PID %d inode_listxattr\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_inode_removexattr(struct dentry *dentry,const char *name){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->inode_removexattr(dentry,name); + } + + pr_alert("judgm:PID %d inode_removexattr\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_inode_need_killpriv(struct dentry *dentry){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->inode_need_killpriv(dentry); + } + + pr_alert("judgm:PID %d inode_need_killpriv\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_inode_killpriv(struct dentry *dentry){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->inode_killpriv(dentry); + } + + pr_alert("judgm:PID %d inode_killpriv\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_inode_getsecurity(const struct inode *inode,const char *name,void **buffer,bool alloc){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->inode_getsecurity(inode,name,buffer,alloc); + } + + pr_alert("judgm:PID %d inode_getsecurity\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_inode_setsecurity(struct inode *inode,const char *name,const void *value,size_t size,int flags){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->inode_setsecurity(inode,name,value,size,flags); + } + + pr_alert("judgm:PID %d inode_setsecurity\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_inode_listsecurity(struct inode *inode,char *buffer,size_t buffer_size){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->inode_listsecurity(inode,buffer,buffer_size); + } + + pr_alert("judgm:PID %d inode_listsecurity\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +/*static int hook_file_alloc_security(struct file *file){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->file_alloc_security(file); + } + + pr_alert("judgm:PID %d file_alloc_security\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; + }*/ +static int hook_file_ioctl(struct file *file,unsigned int cmd,unsigned long arg){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->file_ioctl(file,cmd,arg); + } + + pr_alert("judgm:PID %d file_ioctl\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +/*static int hook_mmap_addr(unsigned long addr){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->mmap_addr(addr); + } + + pr_alert("judgm:PID %d mmap_addr\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; + }*/ +/*static int hook_mmap_file(struct file *file,unsigned long reqprot,unsigned long prot,unsigned long flags){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->mmap_file(file,reqprot,prot,flags); + } + + pr_alert("judgm:PID %d mmap_file\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; + }*/ +/*static int hook_file_mprotect(struct vm_area_struct *vma,unsigned long reqprot,unsigned long prot){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->file_mprotect(vma,reqprot,prot); + } + + pr_alert("judgm:PID %d file_mprotect\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; + }*/ +static int hook_file_lock(struct file *file,unsigned int cmd){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->file_lock(file,cmd); + } + + pr_alert("judgm:PID %d file_lock\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_file_fcntl(struct file *file,unsigned int cmd,unsigned long arg){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->file_fcntl(file,cmd,arg); + } + + pr_alert("judgm:PID %d file_fcntl\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_file_set_fowner(struct file *file){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->file_set_fowner(file); + } + + pr_alert("judgm:PID %d file_set_fowner\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_file_send_sigiotask(struct task_struct *tsk,struct fown_struct *fown,int sig){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->file_send_sigiotask(tsk,fown,sig); + } + + pr_alert("judgm:PID %d file_send_sigiotask\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_file_receive(struct file *file){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->file_receive(file); + } + + pr_alert("judgm:PID %d file_receive\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_task_create(unsigned long clone_flags){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->task_create(clone_flags); + } + + pr_alert("judgm:PID %d task_create\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_cred_alloc_blank(struct cred *cred,gfp_t gfp){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->cred_alloc_blank(cred,gfp); + } + + pr_alert("judgm:PID %d cred_alloc_blank\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +/*static int hook_cred_prepare(struct cred *new,const struct cred *old,gfp_t gfp){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->cred_prepare(new,old,gfp); + } + + pr_alert("judgm:PID %d cred_prepare\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; + }*/ +static int hook_kernel_act_as(struct cred *new,u32 secid){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->kernel_act_as(new,secid); + } + + pr_alert("judgm:PID %d kernel_act_as\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_kernel_create_files_as(struct cred *new,struct inode *inode){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->kernel_create_files_as(new,inode); + } + + pr_alert("judgm:PID %d kernel_create_files_as\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_kernel_module_request(char *kmod_name){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->kernel_module_request(kmod_name); + } + + pr_alert("judgm:PID %d kernel_module_request\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_task_fix_setuid(struct cred *new,const struct cred *old,int flags){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->task_fix_setuid(new,old,flags); + } + + pr_alert("judgm:PID %d task_fix_setuid\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_task_setpgid(struct task_struct *p,pid_t pgid){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->task_setpgid(p,pgid); + } + + pr_alert("judgm:PID %d task_setpgid\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_task_getpgid(struct task_struct *p){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->task_getpgid(p); + } + + pr_alert("judgm:PID %d task_getpgid\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_task_getsid(struct task_struct *p){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->task_getsid(p); + } + + pr_alert("judgm:PID %d task_getsid\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_task_setnice(struct task_struct *p,int nice){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->task_setnice(p,nice); + } + + pr_alert("judgm:PID %d task_setnice\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_task_setioprio(struct task_struct *p,int ioprio){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->task_setioprio(p,ioprio); + } + + pr_alert("judgm:PID %d task_setioprio\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_task_getioprio(struct task_struct *p){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->task_getioprio(p); + } + + pr_alert("judgm:PID %d task_getioprio\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_task_setrlimit(struct task_struct *p,unsigned int resource,struct rlimit *new_rlim){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->task_setrlimit(p,resource,new_rlim); + } + + pr_alert("judgm:PID %d task_setrlimit\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_task_setscheduler(struct task_struct *p){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->task_setscheduler(p); + } + + pr_alert("judgm:PID %d task_setscheduler\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_task_getscheduler(struct task_struct *p){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->task_getscheduler(p); + } + + pr_alert("judgm:PID %d task_getscheduler\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_task_movememory(struct task_struct *p){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->task_movememory(p); + } + + pr_alert("judgm:PID %d task_movememory\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_task_kill(struct task_struct *p,struct siginfo *siginfo,int sig,u32 secid){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->task_kill(p,siginfo,sig,secid); + } + + pr_alert("judgm:PID %d task_kill\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_task_wait(struct task_struct *p){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->task_wait(p); + } + + pr_alert("judgm:PID %d task_wait\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_task_prctl(int option,unsigned long arg2,unsigned long arg3,unsigned long arg4,unsigned long arg5){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->task_prctl(option,arg2,arg3,arg4,arg5); + } + + pr_alert("judgm:PID %d task_prctl\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_ipc_permission(struct kern_ipc_perm *ipcp,short flag){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->ipc_permission(ipcp,flag); + } + + pr_alert("judgm:PID %d ipc_permission\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_msg_msg_alloc_security(struct msg_msg *msg){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->msg_msg_alloc_security(msg); + } + + pr_alert("judgm:PID %d msg_msg_alloc_security\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_msg_queue_alloc_security(struct msg_queue *msq){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->msg_queue_alloc_security(msq); + } + + pr_alert("judgm:PID %d msg_queue_alloc_security\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_msg_queue_associate(struct msg_queue *msq,int msqflg){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->msg_queue_associate(msq,msqflg); + } + + pr_alert("judgm:PID %d msg_queue_associate\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_msg_queue_msgctl(struct msg_queue *msq,int cmd){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->msg_queue_msgctl(msq,cmd); + } + + pr_alert("judgm:PID %d msg_queue_msgctl\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_msg_queue_msgsnd(struct msg_queue *msq,struct msg_msg *msg,int msqflg){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->msg_queue_msgsnd(msq,msg,msqflg); + } + + pr_alert("judgm:PID %d msg_queue_msgsnd\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + 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 judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->msg_queue_msgrcv(msq,msg,target,type,mode); + } + + pr_alert("judgm:PID %d msg_queue_msgrcv\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_shm_alloc_security(struct shmid_kernel *shp){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->shm_alloc_security(shp); + } + + pr_alert("judgm:PID %d shm_alloc_security\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_shm_associate(struct shmid_kernel *shp,int shmflg){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->shm_associate(shp,shmflg); + } + + pr_alert("judgm:PID %d shm_associate\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_shm_shmctl(struct shmid_kernel *shp,int cmd){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->shm_shmctl(shp,cmd); + } + + pr_alert("judgm:PID %d shm_shmctl\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_shm_shmat(struct shmid_kernel *shp,char __user *shmaddr,int shmflg){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->shm_shmat(shp,shmaddr,shmflg); + } + + pr_alert("judgm:PID %d shm_shmat\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_sem_alloc_security(struct sem_array *sma){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->sem_alloc_security(sma); + } + + pr_alert("judgm:PID %d sem_alloc_security\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_sem_associate(struct sem_array *sma,int semflg){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->sem_associate(sma,semflg); + } + + pr_alert("judgm:PID %d sem_associate\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_sem_semctl(struct sem_array *sma,int cmd){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->sem_semctl(sma,cmd); + } + + pr_alert("judgm:PID %d sem_semctl\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_sem_semop(struct sem_array *sma,struct sembuf *sops,unsigned nsops,int alter){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->sem_semop(sma,sops,nsops,alter); + } + + pr_alert("judgm:PID %d sem_semop\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_netlink_send(struct sock *sk,struct sk_buff *skb){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->netlink_send(sk,skb); + } + + pr_alert("judgm:PID %d netlink_send\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_getprocattr(struct task_struct *p,char *name,char **value){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->getprocattr(p,name,value); + } + + pr_alert("judgm:PID %d getprocattr\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_setprocattr(struct task_struct *p,char *name,void *value,size_t size){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->setprocattr(p,name,value,size); + } + + pr_alert("judgm:PID %d setprocattr\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_secid_to_secctx(u32 secid,char **secdata,u32 *seclen){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->secid_to_secctx(secid,secdata,seclen); + } + + pr_alert("judgm:PID %d secid_to_secctx\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_secctx_to_secid(const char *secdata,u32 seclen,u32 *secid){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->secctx_to_secid(secdata,seclen,secid); + } + + pr_alert("judgm:PID %d secctx_to_secid\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_inode_notifysecctx(struct inode *inode,void *ctx,u32 ctxlen){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->inode_notifysecctx(inode,ctx,ctxlen); + } + + pr_alert("judgm:PID %d inode_notifysecctx\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_inode_setsecctx(struct dentry *dentry,void *ctx,u32 ctxlen){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->inode_setsecctx(dentry,ctx,ctxlen); + } + + pr_alert("judgm:PID %d inode_setsecctx\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_inode_getsecctx(struct inode *inode,void **ctx,u32 *ctxlen){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->inode_getsecctx(inode,ctx,ctxlen); + } + + pr_alert("judgm:PID %d inode_getsecctx\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_unix_stream_connect(struct sock *sock,struct sock *other,struct sock *newsk){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->unix_stream_connect(sock,other,newsk); + } + + pr_alert("judgm:PID %d unix_stream_connect\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_unix_may_send(struct socket *sock,struct socket *other){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->unix_may_send(sock,other); + } + + pr_alert("judgm:PID %d unix_may_send\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_socket_create(int family,int type,int protocol,int kern){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->socket_create(family,type,protocol,kern); + } + + pr_alert("judgm:PID %d socket_create\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_socket_post_create(struct socket *sock,int family,int type,int protocol,int kern){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->socket_post_create(sock,family,type,protocol,kern); + } + + pr_alert("judgm:PID %d socket_post_create\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_socket_bind(struct socket *sock,struct sockaddr *address,int addrlen){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->socket_bind(sock,address,addrlen); + } + + pr_alert("judgm:PID %d socket_bind\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_socket_connect(struct socket *sock,struct sockaddr *address,int addrlen){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->socket_connect(sock,address,addrlen); + } + + pr_alert("judgm:PID %d socket_connect\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_socket_listen(struct socket *sock,int backlog){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->socket_listen(sock,backlog); + } + + pr_alert("judgm:PID %d socket_listen\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_socket_accept(struct socket *sock,struct socket *newsock){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->socket_accept(sock,newsock); + } + + pr_alert("judgm:PID %d socket_accept\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_socket_sendmsg(struct socket *sock,struct msghdr *msg,int size){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->socket_sendmsg(sock,msg,size); + } + + pr_alert("judgm:PID %d socket_sendmsg\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_socket_recvmsg(struct socket *sock,struct msghdr *msg,int size,int flags){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->socket_recvmsg(sock,msg,size,flags); + } + + pr_alert("judgm:PID %d socket_recvmsg\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_socket_getsockname(struct socket *sock){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->socket_getsockname(sock); + } + + pr_alert("judgm:PID %d socket_getsockname\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_socket_getpeername(struct socket *sock){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->socket_getpeername(sock); + } + + pr_alert("judgm:PID %d socket_getpeername\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_socket_getsockopt(struct socket *sock,int level,int optname){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->socket_getsockopt(sock,level,optname); + } + + pr_alert("judgm:PID %d socket_getsockopt\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_socket_setsockopt(struct socket *sock,int level,int optname){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->socket_setsockopt(sock,level,optname); + } + + pr_alert("judgm:PID %d socket_setsockopt\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_socket_shutdown(struct socket *sock,int how){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->socket_shutdown(sock,how); + } + + pr_alert("judgm:PID %d socket_shutdown\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_socket_sock_rcv_skb(struct sock *sk,struct sk_buff *skb){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->socket_sock_rcv_skb(sk,skb); + } + + pr_alert("judgm:PID %d socket_sock_rcv_skb\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_socket_getpeersec_stream(struct socket *sock,char __user *optval,int __user *optlen,unsigned len){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->socket_getpeersec_stream(sock,optval,optlen,len); + } + + pr_alert("judgm:PID %d socket_getpeersec_stream\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_socket_getpeersec_dgram(struct socket *sock,struct sk_buff *skb,u32 *secid){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->socket_getpeersec_dgram(sock,skb,secid); + } + + pr_alert("judgm:PID %d socket_getpeersec_dgram\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_sk_alloc_security(struct sock *sk,int family,gfp_t priority){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->sk_alloc_security(sk,family,priority); + } + + pr_alert("judgm:PID %d sk_alloc_security\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_inet_conn_request(struct sock *sk,struct sk_buff *skb,struct request_sock *req){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->inet_conn_request(sk,skb,req); + } + + pr_alert("judgm:PID %d inet_conn_request\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_secmark_relabel_packet(u32 secid){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->secmark_relabel_packet(secid); + } + + pr_alert("judgm:PID %d secmark_relabel_packet\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_tun_dev_create(void){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->tun_dev_create(); + } + + pr_alert("judgm:PID %d tun_dev_create\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_tun_dev_attach(struct sock *sk){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->tun_dev_attach(sk); + } + + pr_alert("judgm:PID %d tun_dev_attach\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_key_alloc(struct key *key,const struct cred *cred,unsigned long flags){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->key_alloc(key,cred,flags); + } + + pr_alert("judgm:PID %d key_alloc\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_key_permission(key_ref_t key_ref,const struct cred *cred,key_perm_t perm){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->key_permission(key_ref,cred,perm); + } + + pr_alert("judgm:PID %d key_permission\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_key_getsecurity(struct key *key,char **_buffer){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->key_getsecurity(key,_buffer); + } + + pr_alert("judgm:PID %d key_getsecurity\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_audit_rule_init(u32 field,u32 op,char *rulestr,void **lsmrule){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->audit_rule_init(field,op,rulestr,lsmrule); + } + + pr_alert("judgm:PID %d audit_rule_init\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_audit_rule_known(struct audit_krule *krule){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->audit_rule_known(krule); + } + + pr_alert("judgm:PID %d audit_rule_known\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} +static int hook_audit_rule_match(u32 secid,u32 field,u32 op,void *lsmrule,struct audit_context *actx){ + struct judgm_proc_info *info; + + info = judgm_proc_task_lookup(current); + if(info == NULL){ + return ori_sops->audit_rule_match(secid,field,op,lsmrule,actx); + } + + pr_alert("judgm:PID %d audit_rule_match\n",current->tgid); + + info->status = JUDGE_RF; + send_sig(SIGKILL,current,0); + return -EACCES; +} diff --git a/judge/judgm_security.h b/judge/judgm_security.h new file mode 100644 index 0000000..f723331 --- /dev/null +++ b/judge/judgm_security.h @@ -0,0 +1,154 @@ +static unsigned long* security_get_addr(void); + +static unsigned long* security_hook_addr; +static struct security_operations *ori_sops; +static struct security_operations hook_sops; + +int judgm_security_hook(void); +int judgm_security_unhook(void); + +extern struct judgm_proc_info* judgm_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 int hook_sb_alloc_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(char *dev_name,struct path *path,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 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,uid_t uid,gid_t gid); +static int hook_path_chroot(struct path *path); +//static int hook_inode_alloc_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 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 int hook_file_permission(struct file *file,int mask); +//static int hook_file_alloc_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 int hook_cred_alloc_blank(struct cred *cred,gfp_t gfp); +//static int hook_cred_prepare(struct cred *new,const struct cred *old,gfp_t gfp); +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 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 *info,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 int hook_ipc_permission(struct kern_ipc_perm *ipcp,short flag); +static int hook_msg_msg_alloc_security(struct msg_msg *msg); +static int hook_msg_queue_alloc_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 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 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 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 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 int hook_inet_conn_request(struct sock *sk,struct sk_buff *skb,struct request_sock *req); +static int hook_secmark_relabel_packet(u32 secid); +static int hook_tun_dev_create(void); +static int hook_tun_dev_attach(struct sock *sk); +static int hook_key_alloc(struct key *key,const struct cred *cred,unsigned long flags); +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); diff --git a/judge/judgm_syscall.c b/judge/judgm_syscall.c new file mode 100644 index 0000000..155e13e --- /dev/null +++ b/judge/judgm_syscall.c @@ -0,0 +1,240 @@ +#include<linux/fs.h> +#include<linux/sched.h> +#include<linux/slab.h> +#include<linux/sort.h> +#include<asm/msr.h> +#include<asm/unistd.h> +#include<asm/uaccess.h> + +#include"judge_def.h" +#include"judgm.h" +#include"judgx_com.h" +#include"judgm_syscall.h" + +int judgm_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 judgm_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)judgm_syscall_ori_table[i]; + } + syscall_addr_restore((unsigned long)(&syscall_table[i - 1]),restore); + + schedule_timeout_interruptible(3 * HZ); + 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; + + judgm_syscall_ori_table = kmalloc(sizeof(unsigned long) * (syscall_max + 1),GFP_KERNEL); + memcpy(judgm_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 judgm_syscall_check(){ + if(judgm_proc_task_lookup(current)){ + return 1; + } + return 0; +} +int judgm_syscall_block(){ + struct judgm_proc_info *info; + + if((info = judgm_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/judge/judgm_syscall.h b/judge/judgm_syscall.h new file mode 100644 index 0000000..b586b0c --- /dev/null +++ b/judge/judgm_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 judgm_syscall_hook(void); +int judgm_syscall_unhook(void); +int judgm_syscall_check(void); +int judgm_syscall_block(void); + +unsigned long *judgm_syscall_ori_table; + +extern struct judgm_proc_info* judgm_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/judge/judgm_syscall_asm.S b/judge/judgm_syscall_asm.S new file mode 100644 index 0000000..df4a1f3 --- /dev/null +++ b/judge/judgm_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 judgm_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 judgm_syscall_ori_table,%rax + jmp *(%rax) +block: + call judgm_syscall_block + mov $-1,%rax + ret diff --git a/judge/judgx.h b/judge/judgx.h new file mode 100644 index 0000000..b1df863 --- /dev/null +++ b/judge/judgx.h @@ -0,0 +1,27 @@ +#define DLL_PUBLIC __attribute__ ((visibility ("default"))) + +struct judgx_proc_info{ + int status; + unsigned long runtime; + unsigned long peakmem; + + char run_path[PATH_MAX + 1]; + char exe_path[PATH_MAX + 1]; + char exe_name[NAME_MAX + 1]; + unsigned long pid; + unsigned long task; + + unsigned long timelimit; + unsigned long hardtimelimit; + unsigned long memlimit; +}; + +typedef void (*judgx_ini_handler)(void *data,char *section,char *key,char *value); +typedef void (*judgx_check_run_fn)(void); + +extern int judgx_ini_load(FILE *f,judgx_ini_handler handler,void *data); +extern int judgx_compile(char *cpppath,char *exepath,char *arg); +extern struct judgx_proc_info* judgx_proc_create(char *runpath,char *exepath,unsigned long timelimit,unsigned long hardtimelimit,unsigned long memlimit); +extern int judgx_proc_run(struct judgx_proc_info *proc_info,judgx_check_run_fn check_run); +extern int judgx_proc_kill(struct judgx_proc_info *proc_info); +extern int judgx_proc_free(struct judgx_proc_info *proc_info); diff --git a/judge/judgx_com.h b/judge/judgx_com.h new file mode 100644 index 0000000..80efc12 --- /dev/null +++ b/judge/judgx_com.h @@ -0,0 +1,19 @@ +#define IOCTL_PROC_ADD _IOWR('x',0x0,int) +#define IOCTL_PROC_GET _IOWR('x',0x1,int) +#define IOCTL_PROC_KILL _IOR('x',0x2,int) +#define IOCTL_PROC_DEL _IOR('x',0x3,int) + +struct judgx_com_proc_add{ + char run_path[PATH_MAX + 1]; + unsigned long pid; + unsigned long task; + unsigned long timelimit; + unsigned long hardtimelimit; + unsigned long memlimit; +}; +struct judgx_com_proc_get{ + unsigned long task; + int status; + unsigned long runtime; + unsigned long peakmem; +}; diff --git a/judge/judgx_lib.c b/judge/judgx_lib.c new file mode 100644 index 0000000..32f5d04 --- /dev/null +++ b/judge/judgx_lib.c @@ -0,0 +1,287 @@ +#define _XOPEN_SOURCE 500 + +#include<stdio.h> +#include<stdlib.h> +#include<string.h> +#include<fcntl.h> +#include<dlfcn.h> +#include<limits.h> +#include<signal.h> +#include<ftw.h> +#include<sys/ioctl.h> +#include<sys/capability.h> +#include<sys/resource.h> +#include<sys/stat.h> + +#include"judge_def.h" +#include"judgx.h" +#include"judgx_com.h" +#include"judgx_lib.h" + +static __attribute__((constructor)) void judgx_init(){ + judgx_modfd = open("/dev/judgm",O_RDWR); + return; +} +static __attribute__((destructor)) void judgx_exit(){ + close(judgx_modfd); + return; +} + +DLL_PUBLIC int judgx_ini_load(FILE *f,judgx_ini_handler handler,void *data){ + int i; + int j; + + char *buf; + int l; + char *section; + char *key; + char *value; + + buf = malloc(1024); + section = malloc(1024); + key = malloc(1024); + value = malloc(1024); + + while(fgets(buf,1024,f) != NULL){ + l = strlen(buf); + if(buf[l - 1] == '\n'){ + buf[l - 1] = '\0'; + } + if(buf[0] == '\0'){ + continue; + } + if(buf[0] == '['){ + for(i = 1,j = 0;i < l && buf[i] != ']';i++,j++){ + section[j] = buf[i]; + } + section[j] = '\0'; + }else{ + for(i = 0,j = 0;i < l && buf[i] != '=';i++,j++){ + key[j] = buf[i]; + } + key[j] = '\0'; + for(i += 1,j = 0;i < l;i++,j++){ + value[j] = buf[i]; + } + value[j] = '\0'; + handler(data,section,key,value); + } + } + + free(buf); + free(section); + free(key); + free(value); + + return 0; +} + +DLL_PUBLIC int judgx_compile(char *cpppath,char *exepath,char *arg){ + int pid; + int waitstatus; + + if((pid = fork()) == 0){ + char *argv[] = {"g++","-static","-O2",cpppath,"-lrt","-o",exepath,NULL}; + + freopen("/dev/null","w",stdout); + freopen("/dev/null","w",stderr); + + execvp("g++",argv); + } + waitpid(pid,&waitstatus,0); + if(waitstatus != 0){ + return JUDGE_CE; + } + return 0; +} + +DLL_PUBLIC struct judgx_proc_info* judgx_proc_create(char *runpath,char *exepath,unsigned long timelimit,unsigned long hardtimelimit,unsigned long memlimit){ + int ret; + int i,j; + + struct stat st; + struct judgx_proc_info *proc_info; + + if(stat(exepath,&st)){ + return NULL; + } + if(!S_ISREG(st.st_mode)){ + return NULL; + } + + proc_info = malloc(sizeof(struct judgx_proc_info)); + if(proc_info == NULL){ + goto error; + } + + proc_info->run_path[0] = '\0'; + strncat(proc_info->run_path,runpath,sizeof(proc_info->run_path)); + proc_info->exe_path[0] = '\0'; + strncat(proc_info->exe_path,exepath,sizeof(proc_info->exe_path)); + + proc_info->exe_name[NAME_MAX] = '\0'; + for(i = 0,j = 0;proc_info->exe_path[i] != '\0' && j < NAME_MAX;i++){ + if(proc_info->exe_path[i] == '/'){ + j = 0; + }else{ + proc_info->exe_name[j] = proc_info->exe_path[i]; + j++; + } + } + proc_info->status = JUDGE_ERR; + proc_info->exe_name[j] = '\0'; + proc_info->pid = -1; + proc_info->task = -1; + proc_info->timelimit = timelimit; + proc_info->hardtimelimit = hardtimelimit; + proc_info->memlimit = memlimit; + proc_info->runtime = 0L; + proc_info->peakmem = 0L; + + return proc_info; + +error: + + if(proc_info != NULL){ + free(proc_info); + } + + return NULL; +} +static int proc_protect(struct judgx_proc_info *proc_info){ + cap_t caps; + struct rlimit limit; + struct judgx_com_proc_add com_proc_add; + + /*caps = cap_init(); + if(cap_set_file(proc_info->path,caps)){ + cap_free(caps); + goto error; + } + cap_free(caps);*/ + + limit.rlim_cur = 1; + limit.rlim_max = limit.rlim_cur; + prlimit(proc_info->pid,RLIMIT_NPROC,&limit,NULL); + + limit.rlim_cur = 8L; + limit.rlim_max = limit.rlim_cur; + prlimit(proc_info->pid,RLIMIT_NOFILE,&limit,NULL); + + /*limit.rlim_cur = (proc_info->timelimit) / 1000L * 2; + limit.rlim_max = limit.rlim_cur; + prlimit(proc_info->pid,RLIMIT_CPU,&limit,NULL);*/ + + /*limit.rlim_cur = proc_info->memlimit * 1024L + 4096L * 128L; + limit.rlim_max = limit.rlim_cur; + prlimit(proc_info->pid,RLIMIT_AS,&limit,NULL);*/ + + com_proc_add.run_path[0] = '\0'; + strncat(com_proc_add.run_path,proc_info->run_path,sizeof(com_proc_add.run_path)); + com_proc_add.pid = proc_info->pid; + com_proc_add.timelimit = proc_info->timelimit * 1000L; + com_proc_add.hardtimelimit = proc_info->hardtimelimit * 1000L; + com_proc_add.memlimit = proc_info->memlimit * 1024L + 4096L * 128L; + if(ioctl(judgx_modfd,IOCTL_PROC_ADD,&com_proc_add)){ + return -1; + } + proc_info->task = com_proc_add.task; + + return 0; +} +DLL_PUBLIC int judgx_proc_run(struct judgx_proc_info *proc_info,judgx_check_run_fn check_run){ + int ret; + + char abspath[PATH_MAX + 1]; + int waitstatus; + struct judgx_com_proc_get com_proc_get; + + ret = 0; + + printf("proc1\n"); + + realpath(proc_info->exe_path,abspath); + if((proc_info->pid = fork()) == 0){ + char *argv[] = {NULL,NULL}; + char *envp[] = {NULL}; + + chdir(proc_info->run_path); + check_run(); + + setgid(99); + setuid(99); + kill(getpid(),SIGSTOP); + + argv[0] = proc_info->exe_name; + execve(abspath,argv,envp); + } + + printf("proc2\n"); + + if(proc_info->pid == -1){ + ret = -1; + goto end; + } + waitpid(proc_info->pid,NULL,WUNTRACED); + + printf("proc3\n"); + + if(proc_protect(proc_info)){ + kill(proc_info->pid,SIGKILL); + ret = -1; + goto end; + } + + printf("proc4\n"); + + kill(proc_info->pid,SIGCONT); + if(waitpid(proc_info->pid,&waitstatus,0) == -1){ + ret = -1; + goto end; + } + + com_proc_get.task = proc_info->task; + if(ioctl(judgx_modfd,IOCTL_PROC_GET,&com_proc_get)){ + ret = -1; + goto end; + } + + printf("proc5 %d\n",com_proc_get.status); + + proc_info->runtime = com_proc_get.runtime; + proc_info->peakmem = com_proc_get.peakmem; + + if(com_proc_get.status != JUDGE_AC){ + proc_info->status = com_proc_get.status; + }else if(proc_info->peakmem > (proc_info->memlimit * 1024L)){ + proc_info->status = JUDGE_MLE; + }else if(proc_info->runtime > (proc_info->timelimit * 1000L)){ + proc_info->status = JUDGE_TLE; + }else if(WIFEXITED(waitstatus) || (WIFSIGNALED(waitstatus) && WTERMSIG(waitstatus) == SIGKILL)){ + proc_info->status = JUDGE_AC; + }else{ + proc_info->status = JUDGE_RE; + } + +end: + + printf("proc6\n"); + + return ret; +} +DLL_PUBLIC int judgx_proc_kill(struct judgx_proc_info *proc_info){ + if(ioctl(judgx_modfd,IOCTL_PROC_KILL,proc_info->task)){ + return -1; + } + return 0; +} +DLL_PUBLIC int judgx_proc_free(struct judgx_proc_info *proc_info){ + if(proc_info->task != -1){ + if(ioctl(judgx_modfd,IOCTL_PROC_DEL,proc_info->task)){ + return -1; + } + } + + free(proc_info); + return 0; +} diff --git a/judge/judgx_lib.h b/judge/judgx_lib.h new file mode 100644 index 0000000..c5c7074 --- /dev/null +++ b/judge/judgx_lib.h @@ -0,0 +1,13 @@ +static __attribute__((constructor)) void judgx_init(void); +static __attribute__((destructor)) void judgx_exit(void); +static int rmdir_callback(const char *path,const struct stat *st,int flag,struct FTW *ftwbuf); +static int proc_protect(struct judgx_proc_info *proc_info); + +static int judgx_modfd; + +DLL_PUBLIC int judgx_ini_load(FILE *f,judgx_ini_handler handler,void *data); +DLL_PUBLIC int judgx_compile(char *cpppath,char *exepath,char *arg); +DLL_PUBLIC struct judgx_proc_info* judgx_proc_create(char *runpath,char *exepath,unsigned long timelimit,unsigned long hardtimelimit,unsigned long memlimit); +DLL_PUBLIC int judgx_proc_run(struct judgx_proc_info *proc_info,judgx_check_run_fn check_run); +DLL_PUBLIC int judgx_proc_kill(struct judgx_proc_info *proc_info); +DLL_PUBLIC int judgx_proc_free(struct judgx_proc_info *proc_info); diff --git a/judge/judgx_line.h b/judge/judgx_line.h new file mode 100644 index 0000000..3823b62 --- /dev/null +++ b/judge/judgx_line.h @@ -0,0 +1,20 @@ +#define JUDGX_LINE_RESULTMAX 64
+
+struct judgx_line_result{
+ int status;
+ int score;
+ int maxscore;
+ unsigned long runtime;
+ unsigned long peakmem;
+};
+struct judgx_line_info{
+ char pro_path[PATH_MAX + 1];
+ char cpp_path[PATH_MAX + 1];
+ char run_path[PATH_MAX + 1];
+ FILE *set_file;
+ void *line_dll;
+ void *check_dll;
+
+ int result_count;
+ struct judgx_line_result result[JUDGX_LINE_RESULTMAX];
+};
diff --git a/judge/line.c b/judge/line.c new file mode 100644 index 0000000..3f9be28 --- /dev/null +++ b/judge/line.c @@ -0,0 +1,195 @@ +#include<stdio.h> +#include<stdlib.h> +#include<string.h> +#include<dlfcn.h> +#include<limits.h> +#include<semaphore.h> +#include<signal.h> +#include<time.h> + +#include"judge_def.h" +#include"judgx.h" +#include"judgx_line.h" +#include"line.h" + +static void line_ini_handler(void *data,char *section,char *key,char *value){ + int i; + + struct line_setting_info *set_info; + char *part; + char *savpart; + + set_info = (struct line_setting_info*)data; + if(strcmp(section,"JUDGE") == 0){ + if(strcmp(key,"timelimit") == 0){ + set_info->timelimit = atoi(value); + }else if(strcmp(key,"hardtimelimit") == 0){ + set_info->hardtimelimit = atoi(value); + }else if(strcmp(key,"memlimit") == 0){ + set_info->memlimit = atoi(value); + }else if(strcmp(key,"count") == 0){ + set_info->count = atoi(value); + }else if(strcmp(key,"score") == 0){ + part = strtok_r(value,",",&savpart); + i = 0; + while(part != NULL){ + set_info->score[i] = atoi(part); + part = strtok_r(NULL,",",&savpart); + i++; + } + } + } +} +static void* line_procrun_thread(void *arg){ + struct line_procrun_info *procrun_info; + + procrun_info = (struct line_procrun_info*)arg; + judgx_proc_run(procrun_info->proc_info,procrun_info->check_run); + + sem_post(procrun_info->done_sem); + return NULL; +} + +DLL_PUBLIC int run(struct judgx_line_info *line_info){ + int ret; + int i; + + struct line_setting_info *set_info; + char exepath[PATH_MAX + 1]; + char datapath[PATH_MAX + 1]; + + check_init_fn check_init; + check_thread_fn check_thread; + check_stop_fn check_stop; + judgx_check_run_fn check_run; + + struct judgx_proc_info *proc_info; + int status; + int score; + unsigned long runtime; + unsigned long peakmem; + + sem_t donesem; + struct check_thread_info thread_info; + struct line_procrun_info procrun_info; + pthread_t check_pt; + pthread_t procrun_pt; + struct timespec waittime; + + printf("line1\n"); + + set_info = malloc(sizeof(struct line_setting_info)); + set_info->hardtimelimit = -1; + judgx_ini_load(line_info->set_file,line_ini_handler,set_info); + if(set_info->hardtimelimit < 0){ + set_info->hardtimelimit = set_info->timelimit * 10L + 10000; + } + + printf("line2\n"); + + check_init = dlsym(line_info->check_dll,"init"); + check_thread = dlsym(line_info->check_dll,"thread"); + check_stop = dlsym(line_info->check_dll,"stop"); + check_run = dlsym(line_info->check_dll,"run"); + + printf("line3\n"); + + snprintf(exepath,sizeof(exepath),"%s/test",line_info->run_path); + if(judgx_compile(line_info->cpp_path,exepath,NULL) == JUDGE_CE){ + for(i = 0;i < set_info->count;i++){ + line_info->result[i].status = JUDGE_CE; + line_info->result[i].score = 0; + line_info->result[i].maxscore = set_info->score[i]; + line_info->result[i].runtime = 0; + line_info->result[i].peakmem = 0; + } + line_info->result_count = set_info->count; + + goto clean; + } + + printf("line4\n"); + + for(i = 0;i < set_info->count;i++){ + status = JUDGE_ERR; + score = 0; + runtime = 0; + peakmem = 0; + + printf("line5\n"); + + if(!(proc_info = judgx_proc_create(line_info->run_path,exepath,set_info->timelimit,set_info->hardtimelimit,set_info->memlimit))){ + goto proc_end; + } + + printf("line7\n"); + + snprintf(datapath,sizeof(datapath),"%s/%d",line_info->pro_path,(i + 1)); + if(check_init(line_info->run_path,datapath)){ + goto proc_clean; + } + + sem_init(&donesem,0,0); + + thread_info.status = JUDGE_WA; + thread_info.done_sem = &donesem; + + procrun_info.proc_info = proc_info; + procrun_info.check_run = check_run; + procrun_info.done_sem = &donesem; + + pthread_create(&check_pt,NULL,check_thread,&thread_info); + pthread_create(&procrun_pt,NULL,line_procrun_thread,&procrun_info); + + sem_wait(&donesem); + + judgx_proc_kill(proc_info); + pthread_join(procrun_pt,NULL); + + check_stop(); + + if(proc_info->status == JUDGE_AC){ + clock_gettime(CLOCK_REALTIME,&waittime); + waittime.tv_sec += CHECK_THREAD_WAITTIME; + if(sem_timedwait(&donesem,&waittime)){ + status = JUDGE_WA; + }else{ + status = thread_info.status; + score = set_info->score[i]; + } + }else{ + status = proc_info->status; + } + + pthread_cancel(check_pt); + sem_destroy(&donesem); + + runtime = proc_info->runtime; + peakmem = proc_info->peakmem; + +proc_clean: + + judgx_proc_free(proc_info); + +proc_end: + + line_info->result[i].status = status; + line_info->result[i].score = score; + line_info->result[i].maxscore = set_info->score[i]; + line_info->result[i].runtime = runtime; + line_info->result[i].peakmem = peakmem; + } + + printf("line8\n"); + + line_info->result_count = set_info->count; + +clean: + + free(set_info); + close(line_info->set_file); + + printf("line10\n"); + + return 0; +} diff --git a/judge/line.h b/judge/line.h new file mode 100644 index 0000000..8864868 --- /dev/null +++ b/judge/line.h @@ -0,0 +1,27 @@ +#define CHECK_THREAD_WAITTIME 5 + +typedef int (*check_init_fn)(char *runpath,char *datapath); +typedef void* (*check_thread_fn)(void *arg); +typedef int (*check_stop_fn)(void); + +struct line_setting_info{ + unsigned long timelimit; + unsigned long hardtimelimit; + unsigned long memlimit; + int count; + int score[JUDGX_LINE_RESULTMAX]; +}; +struct line_procrun_info{ + struct judgx_proc_info *proc_info; + judgx_check_run_fn check_run; + sem_t *done_sem; +}; +struct check_thread_info{ + int status; + sem_t *done_sem; +}; + +static void line_ini_handler(void *data,char *section,char *key,char *value); +static void* line_procrun_thread(void *arg); + +DLL_PUBLIC int run(struct judgx_line_info *line_info); diff --git a/judge/line_vscore.c b/judge/line_vscore.c new file mode 100644 index 0000000..c241495 --- /dev/null +++ b/judge/line_vscore.c @@ -0,0 +1,189 @@ +#include<stdio.h>
+#include<stdlib.h>
+#include<string.h>
+#include<dlfcn.h>
+#include<limits.h>
+#include<semaphore.h>
+#include<signal.h>
+#include<time.h>
+
+#include"judge_def.h"
+#include"judgx.h"
+#include"judgx_line.h"
+#include"line_vscore.h"
+
+static void line_ini_handler(void *data,char *section,char *key,char *value){
+ int i;
+
+ struct line_setting_info *set_info;
+ char *part;
+ char *savpart;
+
+ set_info = (struct line_setting_info*)data;
+ if(strcmp(section,"JUDGE") == 0){
+ if(strcmp(key,"timelimit") == 0){
+ set_info->timelimit = atoi(value);
+ }else if(strcmp(key,"hardtimelimit") == 0){
+ set_info->hardtimelimit = atoi(value);
+ }else if(strcmp(key,"memlimit") == 0){
+ set_info->memlimit = atoi(value);
+ }else if(strcmp(key,"count") == 0){
+ set_info->count = atoi(value);
+ }
+ }
+}
+static void* line_procrun_thread(void *arg){
+ struct line_procrun_info *procrun_info;
+
+ procrun_info = (struct line_procrun_info*)arg;
+ judgx_proc_run(procrun_info->proc_info,procrun_info->check_run);
+
+ sem_post(procrun_info->done_sem);
+ return NULL;
+}
+
+DLL_PUBLIC int run(struct judgx_line_info *line_info){
+ int i;
+
+ struct line_setting_info *set_info;
+ char exepath[PATH_MAX + 1];
+ char datapath[PATH_MAX + 1];
+
+ check_init_fn check_init;
+ check_thread_fn check_thread;
+ check_stop_fn check_stop;
+ judgx_check_run_fn check_run;
+
+ struct judgx_proc_info *proc_info;
+ int status;
+ int score;
+ int maxscore;
+ unsigned long runtime;
+ unsigned long peakmem;
+
+ sem_t donesem;
+ struct check_thread_info thread_info;
+ struct line_procrun_info procrun_info;
+ pthread_t check_pt;
+ pthread_t procrun_pt;
+ struct timespec waittime;
+
+ printf("line1\n");
+
+ set_info = malloc(sizeof(struct line_setting_info));
+ set_info->hardtimelimit = -1;
+ judgx_ini_load(line_info->set_file,line_ini_handler,set_info);
+ if(set_info->hardtimelimit < 0){
+ set_info->hardtimelimit = set_info->timelimit * 10L + 10000;
+ }
+
+ printf("line2\n");
+
+ check_init = dlsym(line_info->check_dll,"init");
+ check_thread = dlsym(line_info->check_dll,"thread");
+ check_stop = dlsym(line_info->check_dll,"stop");
+ check_run = dlsym(line_info->check_dll,"run");
+
+ printf("line3\n");
+
+ snprintf(exepath,sizeof(exepath),"%s/test",line_info->run_path);
+ if(judgx_compile(line_info->cpp_path,exepath,NULL) == JUDGE_CE){
+ for(i = 0;i < set_info->count;i++){
+ line_info->result[i].status = JUDGE_CE;
+ line_info->result[i].score = 0;
+ line_info->result[i].maxscore = 1;
+ line_info->result[i].runtime = 0;
+ line_info->result[i].peakmem = 0;
+ }
+ line_info->result_count = set_info->count;
+
+ goto clean;
+ }
+
+ printf("line4\n");
+
+ for(i = 0;i < set_info->count;i++){
+ status = JUDGE_ERR;
+ score = 0;
+ maxscore = 1;
+ runtime = 0;
+ peakmem = 0;
+
+ printf("line5\n");
+
+ if(!(proc_info = judgx_proc_create(line_info->run_path,exepath,set_info->timelimit,set_info->hardtimelimit,set_info->memlimit))){
+ goto proc_end;
+ }
+
+ printf("line7\n");
+
+ snprintf(datapath,sizeof(datapath),"%s/%d",line_info->pro_path,(i + 1));
+ if(check_init(line_info->run_path,datapath)){
+ goto proc_clean;
+ }
+
+ sem_init(&donesem,0,0);
+
+ thread_info.status = JUDGE_WA;
+ thread_info.done_sem = &donesem;
+
+ procrun_info.proc_info = proc_info;
+ procrun_info.check_run = check_run;
+ procrun_info.done_sem = &donesem;
+
+ pthread_create(&check_pt,NULL,check_thread,&thread_info);
+ pthread_create(&procrun_pt,NULL,line_procrun_thread,&procrun_info);
+
+ sem_wait(&donesem);
+
+ judgx_proc_kill(proc_info);
+ pthread_join(procrun_pt,NULL);
+
+ check_stop();
+
+ if(proc_info->status == JUDGE_AC){
+ clock_gettime(CLOCK_REALTIME,&waittime);
+ waittime.tv_sec += CHECK_THREAD_WAITTIME;
+ if(sem_timedwait(&donesem,&waittime)){
+ status = JUDGE_WA;
+ }else{
+ status = thread_info.status;
+ score = thread_info.score;
+ maxscore = thread_info.maxscore;
+ }
+ }else{
+ status = proc_info->status;
+ }
+
+ pthread_cancel(check_pt);
+ sem_destroy(&donesem);
+
+ runtime = proc_info->runtime;
+ peakmem = proc_info->peakmem;
+
+proc_clean:
+
+ judgx_proc_free(proc_info);
+
+proc_end:
+
+ line_info->result[i].status = status;
+ line_info->result[i].score = score;
+ line_info->result[i].maxscore = maxscore;
+ line_info->result[i].runtime = runtime;
+ line_info->result[i].peakmem = peakmem;
+ }
+
+ printf("line8\n");
+
+ line_info->result_count = set_info->count;
+
+clean:
+
+ free(set_info);
+ close(line_info->set_file);
+
+ printf("line10\n");
+
+ return 0;
+}
diff --git a/judge/line_vscore.h b/judge/line_vscore.h new file mode 100644 index 0000000..3609e88 --- /dev/null +++ b/judge/line_vscore.h @@ -0,0 +1,28 @@ +#define CHECK_THREAD_WAITTIME 5 + +typedef int (*check_init_fn)(char *runpath,char *datapath); +typedef void* (*check_thread_fn)(void *arg); +typedef int (*check_stop_fn)(void); + +struct line_setting_info{ + unsigned long timelimit; + unsigned long hardtimelimit; + unsigned long memlimit; + int count; +}; +struct line_procrun_info{ + struct judgx_proc_info *proc_info; + judgx_check_run_fn check_run; + sem_t *done_sem; +}; +struct check_thread_info{ + int status; + int score; + int maxscore; + sem_t *done_sem; +}; + +static void line_ini_handler(void *data,char *section,char *key,char *value); +static void* line_procrun_thread(void *arg); + +DLL_PUBLIC int run(struct judgx_line_info *line_info); |