X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fum%2Fkernel%2Ftt%2Fsyscall_kern.c;h=293caa6d0c2dd7bc84e839d57ed214d12a83994b;hb=a2f44b27303a5353859d77a3e96a1d3f33f56ab7;hp=555ffd0ee3478393018da18eb147e6315cfe02f9;hpb=a803a40191c815e7162501eddcf9a7e39ba63046;p=linux-2.6.git diff --git a/arch/um/kernel/tt/syscall_kern.c b/arch/um/kernel/tt/syscall_kern.c index 555ffd0ee..293caa6d0 100644 --- a/arch/um/kernel/tt/syscall_kern.c +++ b/arch/um/kernel/tt/syscall_kern.c @@ -12,133 +12,35 @@ #include "asm/uaccess.h" #include "asm/stat.h" #include "sysdep/syscalls.h" +#include "sysdep/sigcontext.h" #include "kern_util.h" +#include "syscall.h" -static inline int check_area(void *ptr, int size) +void syscall_handler_tt(int sig, struct pt_regs *regs) { - return(verify_area(VERIFY_WRITE, ptr, size)); -} - -static int check_readlink(struct pt_regs *regs) -{ - return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs), - UPT_SYSCALL_ARG2(®s->regs))); -} - -static int check_utime(struct pt_regs *regs) -{ - return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs), - sizeof(struct utimbuf))); -} - -static int check_oldstat(struct pt_regs *regs) -{ - return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs), - sizeof(struct __old_kernel_stat))); -} - -static int check_stat(struct pt_regs *regs) -{ - return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs), - sizeof(struct stat))); -} - -static int check_stat64(struct pt_regs *regs) -{ - return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs), - sizeof(struct stat64))); -} - -struct bogus { - int kernel_ds; - int (*check_params)(struct pt_regs *); -}; - -struct bogus this_is_bogus[256] = { - [ __NR_mknod ] = { 1, NULL }, - [ __NR_mkdir ] = { 1, NULL }, - [ __NR_rmdir ] = { 1, NULL }, - [ __NR_unlink ] = { 1, NULL }, - [ __NR_symlink ] = { 1, NULL }, - [ __NR_link ] = { 1, NULL }, - [ __NR_rename ] = { 1, NULL }, - [ __NR_umount ] = { 1, NULL }, - [ __NR_mount ] = { 1, NULL }, - [ __NR_pivot_root ] = { 1, NULL }, - [ __NR_chdir ] = { 1, NULL }, - [ __NR_chroot ] = { 1, NULL }, - [ __NR_open ] = { 1, NULL }, - [ __NR_quotactl ] = { 1, NULL }, - [ __NR_sysfs ] = { 1, NULL }, - [ __NR_readlink ] = { 1, check_readlink }, - [ __NR_acct ] = { 1, NULL }, - [ __NR_execve ] = { 1, NULL }, - [ __NR_uselib ] = { 1, NULL }, - [ __NR_statfs ] = { 1, NULL }, - [ __NR_truncate ] = { 1, NULL }, - [ __NR_access ] = { 1, NULL }, - [ __NR_chmod ] = { 1, NULL }, - [ __NR_chown ] = { 1, NULL }, - [ __NR_lchown ] = { 1, NULL }, - [ __NR_utime ] = { 1, check_utime }, - [ __NR_oldlstat ] = { 1, check_oldstat }, - [ __NR_oldstat ] = { 1, check_oldstat }, - [ __NR_stat ] = { 1, check_stat }, - [ __NR_lstat ] = { 1, check_stat }, - [ __NR_stat64 ] = { 1, check_stat64 }, - [ __NR_lstat64 ] = { 1, check_stat64 }, - [ __NR_chown32 ] = { 1, NULL }, -}; - -/* sys_utimes */ - -static int check_bogosity(struct pt_regs *regs) -{ - struct bogus *bogon = &this_is_bogus[UPT_SYSCALL_NR(®s->regs)]; - - if(!bogon->kernel_ds) return(0); - if(bogon->check_params && (*bogon->check_params)(regs)) - return(-EFAULT); - set_fs(KERNEL_DS); - return(0); -} + void *sc; + long result; + int syscall; -extern syscall_handler_t *sys_call_table[]; + sc = UPT_SC(®s->regs); + SC_START_SYSCALL(sc); -long execute_syscall_tt(void *r) -{ - struct pt_regs *regs = r; - long res; - int syscall; + syscall = UPT_SYSCALL_NR(®s->regs); + syscall_trace(®s->regs, 0); current->thread.nsyscalls++; nsyscalls++; - syscall = UPT_SYSCALL_NR(®s->regs); if((syscall >= NR_syscalls) || (syscall < 0)) - res = -ENOSYS; - else if(honeypot && check_bogosity(regs)) - res = -EFAULT; - else res = EXECUTE_SYSCALL(syscall, regs); + result = -ENOSYS; + else result = EXECUTE_SYSCALL(syscall, regs); - set_fs(USER_DS); + /* regs->sc may have changed while the system call ran (there may + * have been an interrupt or segfault), so it needs to be refreshed. + */ + UPT_SC(®s->regs) = sc; - if(current->thread.mode.tt.singlestep_syscall){ - current->thread.mode.tt.singlestep_syscall = 0; - current->ptrace &= ~PT_DTRACE; - force_sig(SIGTRAP, current); - } + SC_SET_SYSCALL_RETURN(sc, result); - return(res); + syscall_trace(®s->regs, 1); } - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */