X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fsparc%2Fkernel%2Fsys_sparc.c;h=a954a0c000002410e518e05f9ba905e8f53ff31a;hb=refs%2Fheads%2Fvserver;hp=925efe9922e7ae4714db48ea6e4cb79a31544889;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c index 925efe992..a954a0c00 100644 --- a/arch/sparc/kernel/sys_sparc.c +++ b/arch/sparc/kernel/sys_sparc.c @@ -24,6 +24,7 @@ #include #include +#include /* #define DEBUG_UNIMP_SYSCALL */ @@ -136,7 +137,8 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void __user if (!ptr) goto out; err = -EFAULT; - if(get_user(fourth.__pad, (void __user **)ptr)) + if (get_user(fourth.__pad, + (void __user * __user *)ptr)) goto out; err = sys_semctl (first, second, third, fourth); goto out; @@ -165,7 +167,9 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void __user goto out; } case 1: default: - err = sys_msgrcv (first, (struct msgbuf *) ptr, second, fifth, third); + err = sys_msgrcv (first, + (struct msgbuf __user *) ptr, + second, fifth, third); goto out; } case MSGGET: @@ -194,7 +198,7 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void __user goto out; } case 1: /* iBCS2 emulator entry point */ - err = do_shmat (first, (char __user *) ptr, second, (ulong __user *) third); + err = -EINVAL; goto out; } case SHMDT: @@ -216,6 +220,21 @@ out: return err; } +int sparc_mmap_check(unsigned long addr, unsigned long len, unsigned long flags) +{ + if (ARCH_SUN4C_SUN4 && + (len > 0x20000000 || + ((flags & MAP_FIXED) && + addr < 0xe0000000 && addr + len > 0x20000000))) + return -EINVAL; + + /* See asm-sparc/uaccess.h */ + if (len > TASK_SIZE - PAGE_SIZE || addr + len > TASK_SIZE - PAGE_SIZE) + return -EINVAL; + + return 0; +} + /* Linux version of mmap */ static unsigned long do_mmap2(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, @@ -230,25 +249,13 @@ static unsigned long do_mmap2(unsigned long addr, unsigned long len, goto out; } - retval = -EINVAL; len = PAGE_ALIGN(len); - if (ARCH_SUN4C_SUN4 && - (len > 0x20000000 || - ((flags & MAP_FIXED) && - addr < 0xe0000000 && addr + len > 0x20000000))) - goto out_putf; - - /* See asm-sparc/uaccess.h */ - if (len > TASK_SIZE - PAGE_SIZE || addr + len > TASK_SIZE - PAGE_SIZE) - goto out_putf; - flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); down_write(¤t->mm->mmap_sem); retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); up_write(¤t->mm->mmap_sem); -out_putf: if (file) fput(file); out: @@ -371,7 +378,7 @@ sparc_breakpoint (struct pt_regs *regs) info.si_signo = SIGTRAP; info.si_errno = 0; info.si_code = TRAP_BRKPT; - info.si_addr = (void *)regs->pc; + info.si_addr = (void __user *)regs->pc; info.si_trapno = 0; force_sig_info(SIGTRAP, &info, current); @@ -396,7 +403,7 @@ sparc_sigaction (int sig, const struct old_sigaction __user *act, if (act) { unsigned long mask; - if (verify_area(VERIFY_READ, act, sizeof(*act)) || + if (!access_ok(VERIFY_READ, act, sizeof(*act)) || __get_user(new_ka.sa.sa_handler, &act->sa_handler) || __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) return -EFAULT; @@ -414,7 +421,7 @@ sparc_sigaction (int sig, const struct old_sigaction __user *act, * deadlock us if we held the signal lock on SMP. So for * now I take the easy way out and do no locking. */ - if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) || + if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) return -EFAULT; @@ -462,21 +469,45 @@ sys_rt_sigaction(int sig, asmlinkage int sys_getdomainname(char __user *name, int len) { - int nlen; - int err = -EFAULT; + int nlen, err; + if (len < 0) + return -EINVAL; + down_read(&uts_sem); - nlen = strlen(system_utsname.domainname) + 1; - - if (nlen < len) - len = nlen; - if (len > __NEW_UTS_LEN) - goto done; - if (copy_to_user(name, system_utsname.domainname, len)) - goto done; - err = 0; -done: + nlen = strlen(utsname()->domainname) + 1; + err = -EINVAL; + if (nlen > len) + goto out; + + err = -EFAULT; + if (!copy_to_user(name, utsname()->domainname, nlen)) + err = 0; + +out: up_read(&uts_sem); return err; } + +/* + * Do a system call from kernel instead of calling sys_execve so we + * end up with proper pt_regs. + */ +int kernel_execve(const char *filename, char *const argv[], char *const envp[]) +{ + long __res; + register long __g1 __asm__ ("g1") = __NR_execve; + register long __o0 __asm__ ("o0") = (long)(filename); + register long __o1 __asm__ ("o1") = (long)(argv); + register long __o2 __asm__ ("o2") = (long)(envp); + asm volatile ("t 0x10\n\t" + "bcc 1f\n\t" + "mov %%o0, %0\n\t" + "sub %%g0, %%o0, %0\n\t" + "1:\n\t" + : "=r" (__res), "=&r" (__o0) + : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) + : "cc"); + return __res; +}