X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fsparc%2Fkernel%2Fsys_sparc.c;h=a954a0c000002410e518e05f9ba905e8f53ff31a;hb=refs%2Fheads%2Fvserver;hp=07879079a53e6d3facdb489efa41b33071587d8f;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c index 07879079a..a954a0c00 100644 --- a/arch/sparc/kernel/sys_sparc.c +++ b/arch/sparc/kernel/sys_sparc.c @@ -21,10 +21,10 @@ #include #include #include -#include #include #include +#include /* #define DEBUG_UNIMP_SYSCALL */ @@ -198,8 +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 *) third); + err = -EINVAL; goto out; } case SHMDT: @@ -221,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, @@ -235,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: @@ -401,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; @@ -419,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; @@ -467,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(vx_new_uts(domainname)) + 1; - - if (nlen < len) - len = nlen; - if (len > __NEW_UTS_LEN) - goto done; - if (copy_to_user(name, vx_new_uts(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; +}