diff options
author | pzread <netfirewall@gmail.com> | 2013-04-13 16:11:19 +0800 |
---|---|---|
committer | pzread <netfirewall@gmail.com> | 2013-04-13 16:11:19 +0800 |
commit | 9b5ecb2fedf4cfd014bf78c51eb79237d8beefc6 (patch) | |
tree | 70d5bdf98d0992f8ed3b00204050a47d88291a80 | |
parent | b7f29ae6f2818405bbb043cf986c95cad07d2232 (diff) | |
download | taiwan-online-judge-testing.tar.gz taiwan-online-judge-testing.tar.zst taiwan-online-judge-testing.zip |
Improve linux secuirty module hooktesting
-rwxr-xr-x | toj/center/src/Makefile | 2 | ||||
-rwxr-xr-x | toj/center/src/judgk_security.c | 96 | ||||
-rwxr-xr-x | toj/center/src/judgk_security.h | 10 | ||||
-rwxr-xr-x | toj/center/src/judgk_syscall.c | 13 | ||||
-rwxr-xr-x | toj/center/src/judgk_syscall.h | 5 | ||||
-rwxr-xr-x | toj/center/src/judgk_syscall_asm.S | 24 |
6 files changed, 86 insertions, 64 deletions
diff --git a/toj/center/src/Makefile b/toj/center/src/Makefile index 5dfadda..17cbcf3 100755 --- a/toj/center/src/Makefile +++ b/toj/center/src/Makefile @@ -2,7 +2,7 @@ ifneq ($(KERNELRELEASE),) judgk-objs := judgk_mod.o judgk_proc.o judgk_syscall.o judgk_syscall_asm.o judgk_security.o judgk_security_asm.o judgk_hyperio.o obj-m := judgk.o else - KERNEL_SOURCE := /usr/lib/modules/3.8.4-1-ARCH/build + KERNEL_SOURCE := /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) default: ${MAKE} -C ${KERNEL_SOURCE} M=${PWD} modules diff --git a/toj/center/src/judgk_security.c b/toj/center/src/judgk_security.c index 342aaad..d998223 100755 --- a/toj/center/src/judgk_security.c +++ b/toj/center/src/judgk_security.c @@ -23,14 +23,14 @@ int judgk_security_hook(){ ori_sops = (struct security_operations*)*security_hook_addr; memcpy(&hook_sops,ori_sops,sizeof(struct security_operations)); + judgk_security_checkaddr = (unsigned long)security_check; + count = (sizeof(hook_sops) - sizeof(hook_sops.name)) / sizeof(unsigned long); len = (judgk_security_blockend - judgk_security_block) + sizeof(unsigned long); security_block_code = __vmalloc(((((len * count - 1) >> PAGE_SHIFT) + 1) << PAGE_SHIFT),GFP_KERNEL | GFP_ATOMIC,PAGE_KERNEL_EXEC); - judgk_security_checkaddr = (unsigned long)security_check; - - ori_array = (unsigned long*)(((char*)ori_sops) + sizeof(hook_sops.name)); - hook_array = (unsigned long*)(((char*)&hook_sops) + sizeof(hook_sops.name)); + ori_array = (unsigned long*)(((char*)ori_sops) + offsetof(struct security_operations,ptrace_access_check)); + hook_array = (unsigned long*)(((char*)&hook_sops) + offsetof(struct security_operations,ptrace_access_check)); for(i = 0;i < count;i++){ addr = (((char*)security_block_code) + len * i); memcpy(addr,&ori_array[i],sizeof(unsigned long)); @@ -38,24 +38,31 @@ int judgk_security_hook(){ hook_array[i] = (unsigned long)addr + sizeof(unsigned long); } - //hook_sops.capable = hook_capable; - //hook_sops.bprm_set_creds = hook_bprm_set_creds; - //hook_sops.bprm_check_security = hook_bprm_check_security; - //hook_sops.bprm_secureexec = hook_bprm_secureexec; - //hook_sops.bprm_committing_creds = hook_bprm_committing_creds; - //hook_sops.bprm_committed_creds = hook_bprm_committed_creds; - //hook_sops.inode_alloc_security = hook_inode_alloc_security; - //hook_sops.inode_free_security = hook_inode_free_security; - //hook_sops.inode_follow_link = hook_inode_follow_link; - //hook_sops.inode_getattr = hook_inode_getattr; - //hook_sops.file_alloc_security = hook_file_alloc_security; - //hook_sops.file_free_security = hook_file_free_security; - //hook_sops.mmap_addr = hook_mmap_addr; - //hook_sops.mmap_file = hook_mmap_file; - //hook_sops.file_mprotect = hook_file_mprotect; - //hook_sops.task_free = hook_task_free; - //hook_sops.cred_free = hook_cred_free; - //hook_sops.cred_prepare = hook_cred_prepare; + hook_sops.capable = ori_sops->capable; + hook_sops.bprm_set_creds = ori_sops->bprm_set_creds; + hook_sops.bprm_check_security = ori_sops->bprm_check_security; + hook_sops.bprm_secureexec = ori_sops->bprm_secureexec; + hook_sops.bprm_committing_creds = ori_sops->bprm_committing_creds; + hook_sops.bprm_committed_creds = ori_sops->bprm_committed_creds; + hook_sops.inode_alloc_security = ori_sops->inode_alloc_security; + hook_sops.inode_free_security = ori_sops->inode_free_security; + hook_sops.inode_follow_link = ori_sops->inode_follow_link; + hook_sops.inode_getattr = ori_sops->inode_getattr; + hook_sops.file_alloc_security = ori_sops->file_alloc_security; + hook_sops.file_free_security = ori_sops->file_free_security; + hook_sops.mmap_addr = ori_sops->mmap_addr; + hook_sops.mmap_file = ori_sops->mmap_file; + hook_sops.file_mprotect = ori_sops->file_mprotect; + hook_sops.task_free = ori_sops->task_free; + hook_sops.cred_free = ori_sops->cred_free; + hook_sops.cred_prepare = ori_sops->cred_prepare; + + hook_sops.inode_permission = hook_inode_permission; + hook_sops.file_permission = hook_file_permission; + hook_sops.file_open = hook_file_open; + hook_sops.file_ioctl = hook_file_ioctl; + hook_sops.d_instantiate = hook_d_instantiate; + hook_sops.vm_enough_memory = hook_vm_enough_memory; *security_hook_addr = (unsigned long)&hook_sops; @@ -144,7 +151,10 @@ static int security_init_hook(){ return 0; } -static unsigned long security_check(void){ +static inline void security_kill(void){ + send_sig(SIGKILL,current,0); +} +static long security_check(void){ struct judgk_proc_info *info; info = judgk_proc_task_lookup(current); @@ -152,15 +162,13 @@ static unsigned long security_check(void){ return 0; } - pr_alert("judgk:PID %d Security block\n",current->tgid); + pr_alert("judgk:PID %d RF\n",current->tgid); + + info->status = JUDGE_RF; + security_kill(); - security_hook_rf(info); return -EACCES; } -static inline void security_hook_rf(struct judgk_proc_info *info){ - info->status = JUDGE_RF; - send_sig(SIGKILL,current,0); -} static int hook_inode_permission(struct inode *inode,int mask){ struct judgk_proc_info *info; @@ -173,7 +181,9 @@ static int hook_inode_permission(struct inode *inode,int mask){ if((mask & ~(MAY_EXEC | MAY_READ | MAY_OPEN | MAY_CHDIR | MAY_NOT_BLOCK)) != 0){ pr_alert("judgk:PID %d RF inode_permission %08x\n",current->tgid,mask); - security_hook_rf(info); + info->status = JUDGE_RF; + security_kill(); + return -EACCES; } return ori_sops->inode_permission(inode,mask); @@ -187,10 +197,14 @@ static int hook_file_permission(struct file *file,int mask){ } if((mask & ~(MAY_READ | MAY_WRITE)) != 0){ - security_hook_rf(info); + info->status = JUDGE_RF; + security_kill(); + return -EACCES; }else if((mask & MAY_WRITE) != 0 && file != info->std_out){ - security_hook_rf(info); + info->status = JUDGE_RF; + security_kill(); + return -EACCES; } return ori_sops->file_permission(file,mask); @@ -232,7 +246,9 @@ static int hook_file_open(struct file *file, const struct cred *cred){ if(ret != 0){ pr_alert("judgk:PID %d RF file_open %s %08x\n",current->tgid,path,file->f_mode); - security_hook_rf(info); + info->status = JUDGE_RF; + security_kill(); + return ret; } return ori_sops->file_open(file,cred); @@ -248,7 +264,9 @@ static int hook_file_ioctl(struct file *file,unsigned int cmd,unsigned long arg) if(file != info->std_in && file != info->std_out){ pr_alert("judgk:PID %d file_ioctl\n",current->tgid); - security_hook_rf(info); + info->status = JUDGE_RF; + security_kill(); + return -EACCES; } return ori_sops->file_ioctl(file,cmd,arg); @@ -263,7 +281,9 @@ static void hook_d_instantiate(struct dentry *dentry,struct inode *inode){ if(inode == NULL || inode->i_ino != security_meminfo_ino){ pr_alert("judgk:PID %d d_instantiate\n",current->tgid); - security_hook_rf(info); + + info->status = JUDGE_RF; + security_kill(); } return ori_sops->d_instantiate(dentry,inode); } @@ -276,11 +296,13 @@ static int hook_vm_enough_memory(struct mm_struct *mm,long pages){ } info->memory = (mm->total_vm + pages) << PAGE_SHIFT; - //pr_alert("judgk:PID %d vm_enough_memory %lu\n",current->tgid,info->memory); if(info->memory > info->memlimit){ + pr_alert("judgk:PID %d vm_enough_memory %lu\n",current->tgid,info->memory); + info->status = JUDGE_MLE; - send_sig(SIGKILL,current,0); + security_kill(); + return -EACCES; } return ori_sops->vm_enough_memory(mm,pages); diff --git a/toj/center/src/judgk_security.h b/toj/center/src/judgk_security.h index 1816786..3855d7b 100755 --- a/toj/center/src/judgk_security.h +++ b/toj/center/src/judgk_security.h @@ -1,6 +1,6 @@ static int security_init_hook(void); -static unsigned long security_check(void); -static inline void security_hook_rf(struct judgk_proc_info *info); +static inline void security_kill(void); +static long security_check(void); static unsigned long security_meminfo_ino; static unsigned long* security_hook_addr; @@ -17,3 +17,9 @@ extern struct judgk_proc_info* judgk_proc_task_lookup(struct task_struct *task); extern void judgk_security_block(void); extern void judgk_security_blockend(void); +static int hook_inode_permission(struct inode *inode,int mask); +static int hook_file_permission(struct file *file,int mask); +static int hook_file_open(struct file *file, const struct cred *cred); +static int hook_file_ioctl(struct file *file,unsigned int cmd,unsigned long arg); +static void hook_d_instantiate(struct dentry *dentry,struct inode *inode); +static int hook_vm_enough_memory(struct mm_struct *mm,long pages); diff --git a/toj/center/src/judgk_syscall.c b/toj/center/src/judgk_syscall.c index 370a3fe..c876283 100755 --- a/toj/center/src/judgk_syscall.c +++ b/toj/center/src/judgk_syscall.c @@ -32,7 +32,7 @@ int judgk_syscall_hook(){ j++; continue; } - syscall_table[i] = (unsigned long)hook_sys_block; + syscall_table[i] = (unsigned long)judgk_syscall_block; } syscall_addr_restore((unsigned long)(&syscall_table[i - 1]),restore); @@ -198,13 +198,7 @@ static int syscall_addr_restore(unsigned long addr,int restore){ return 0; } -int judgk_syscall_check(){ - if(judgk_proc_task_lookup(current)){ - return 1; - } - return 0; -} -int judgk_syscall_block(){ +long judgk_syscall_check(){ struct judgk_proc_info *info; if((info = judgk_proc_task_lookup(current)) == NULL){ @@ -213,7 +207,8 @@ int judgk_syscall_block(){ info->status = JUDGE_RF; send_sig(SIGKILL,current,0); - return 0; + + return -EACCES; } /*asmlinkage long hook_sys_nanosleep(struct timespec __user *rqtp,struct timespec __user *rmtp){ diff --git a/toj/center/src/judgk_syscall.h b/toj/center/src/judgk_syscall.h index 2ee6afb..143a2db 100755 --- a/toj/center/src/judgk_syscall.h +++ b/toj/center/src/judgk_syscall.h @@ -57,13 +57,12 @@ static unsigned int syscall_whitelist[SYSCALL_WHITELIST_SIZE] = { int judgk_syscall_hook(void); int judgk_syscall_unhook(void); -int judgk_syscall_check(void); -int judgk_syscall_block(void); +long judgk_syscall_check(void); unsigned long *judgk_syscall_ori_table; extern struct judgk_proc_info* judgk_proc_task_lookup(struct task_struct *task); -extern long hook_sys_block(void); +extern long judgk_syscall_block(void); //typedef asmlinkage long (*func_sys_nanosleep)(struct timespec __user *rqtp,struct timespec __user *rmtp); //func_sys_nanosleep ori_sys_nanosleep; diff --git a/toj/center/src/judgk_syscall_asm.S b/toj/center/src/judgk_syscall_asm.S index dfc5bc6..03ff960 100755 --- a/toj/center/src/judgk_syscall_asm.S +++ b/toj/center/src/judgk_syscall_asm.S @@ -1,10 +1,9 @@ .code64 -.section .data .section .text -.global hook_sys_block -.type hook_sys_block,@function +.global judgk_syscall_block +.extern judgk_syscall_check -hook_sys_block: +judgk_syscall_block: push %rax push %rbx push %rcx @@ -20,10 +19,11 @@ hook_sys_block: push %r13 push %r14 push %r15 + pushfq call judgk_syscall_check - test %eax,%eax - + + popfq pop %r15 pop %r14 pop %r13 @@ -38,17 +38,17 @@ hook_sys_block: pop %rdx pop %rcx pop %rbx - pop %rax - jnz block + test %rax,%rax + pop %rax + jnz .block - push %rdx + push %rdx //use rdx, because mul rax => rdx:rax, kill two birds with one stone mov $8,%rdx mul %rdx pop %rdx add judgk_syscall_ori_table,%rax jmp *(%rax) -block: - call judgk_syscall_block - mov $-1,%rax + +.block: ret |