From 065ee7e9f1ef8368f533c160c016b9ed851f7f80 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Fri, 3 Apr 2009 00:36:27 -0700 Subject: [PATCH] --- yaml --- r: 169999 b: refs/heads/master c: da3f6f9b3e0d1e73975ca81ae124406bf1587d40 h: refs/heads/master i: 169997: f805c0522eaf7071285bfbff7ffa4dbd3a8a835b 169995: aacf77c3dff244b67b1ca3a91ca756eeaa72137c 169991: 71a030c44c8e712ba3e443a9911fd6a91e8a3d0c 169983: e3df3fc003619bb1dd302bc11a3f6d1e7a989efa v: v3 --- [refs] | 2 +- trunk/arch/powerpc/kernel/sys_ppc32.c | 52 --------------------------- trunk/kernel/sysctl_binary.c | 50 ++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 53 deletions(-) diff --git a/[refs] b/[refs] index 1c586ce72b4f..5d56567a83a4 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 2830b68361a9f58354ad043c6d85043ea917f907 +refs/heads/master: da3f6f9b3e0d1e73975ca81ae124406bf1587d40 diff --git a/trunk/arch/powerpc/kernel/sys_ppc32.c b/trunk/arch/powerpc/kernel/sys_ppc32.c index b97c2d67f4ac..c5a4732bcc48 100644 --- a/trunk/arch/powerpc/kernel/sys_ppc32.c +++ b/trunk/arch/powerpc/kernel/sys_ppc32.c @@ -520,58 +520,6 @@ asmlinkage long compat_sys_umask(u32 mask) return sys_umask((int)mask); } -#ifdef CONFIG_SYSCTL_SYSCALL -struct __sysctl_args32 { - u32 name; - int nlen; - u32 oldval; - u32 oldlenp; - u32 newval; - u32 newlen; - u32 __unused[4]; -}; - -asmlinkage long compat_sys_sysctl(struct __sysctl_args32 __user *args) -{ - struct __sysctl_args32 tmp; - int error; - size_t oldlen; - size_t __user *oldlenp = NULL; - unsigned long addr = (((unsigned long)&args->__unused[0]) + 7) & ~7; - - if (copy_from_user(&tmp, args, sizeof(tmp))) - return -EFAULT; - - if (tmp.oldval && tmp.oldlenp) { - /* Duh, this is ugly and might not work if sysctl_args - is in read-only memory, but do_sysctl does indirectly - a lot of uaccess in both directions and we'd have to - basically copy the whole sysctl.c here, and - glibc's __sysctl uses rw memory for the structure - anyway. */ - oldlenp = (size_t __user *)addr; - if (get_user(oldlen, (compat_size_t __user *)compat_ptr(tmp.oldlenp)) || - put_user(oldlen, oldlenp)) - return -EFAULT; - } - - lock_kernel(); - error = do_sysctl(compat_ptr(tmp.name), tmp.nlen, - compat_ptr(tmp.oldval), oldlenp, - compat_ptr(tmp.newval), tmp.newlen); - unlock_kernel(); - if (oldlenp) { - if (!error) { - if (get_user(oldlen, oldlenp) || - put_user(oldlen, (compat_size_t __user *)compat_ptr(tmp.oldlenp))) - error = -EFAULT; - } - copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)); - } - return error; -} -#endif - unsigned long compat_sys_mmap2(unsigned long addr, size_t len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff) diff --git a/trunk/kernel/sysctl_binary.c b/trunk/kernel/sysctl_binary.c index 930a31cd708b..775cc49da622 100644 --- a/trunk/kernel/sysctl_binary.c +++ b/trunk/kernel/sysctl_binary.c @@ -176,3 +176,53 @@ SYSCALL_DEFINE1(sysctl, struct __sysctl_args __user *, args) return error; } + +#ifdef CONFIG_COMPAT +#include + +struct compat_sysctl_args { + compat_uptr_t name; + int nlen; + compat_uptr_t oldval; + compat_uptr_t oldlenp; + compat_uptr_t newval; + compat_size_t newlen; + compat_ulong_t __unused[4]; +}; + +asmlinkage long compat_sys_sysctl(struct compat_sysctl_args __user *args) +{ + struct compat_sysctl_args tmp; + compat_size_t __user *compat_oldlenp; + size_t __user *oldlenp = NULL; + size_t oldlen = 0; + ssize_t result; + + if (copy_from_user(&tmp, args, sizeof(tmp))) + return -EFAULT; + + compat_oldlenp = compat_ptr(tmp.oldlenp); + if (compat_oldlenp) { + oldlenp = compat_alloc_user_space(sizeof(*compat_oldlenp)); + + if (get_user(oldlen, compat_oldlenp) || + put_user(oldlen, oldlenp)) + return -EFAULT; + } + + lock_kernel(); + result = do_sysctl(compat_ptr(tmp.name), tmp.nlen, + compat_ptr(tmp.oldval), oldlenp, + compat_ptr(tmp.newval), tmp.newlen); + unlock_kernel(); + + if (oldlenp && !result) { + if (get_user(oldlen, oldlenp) || + put_user(oldlen, compat_oldlenp)) + return -EFAULT; + } + + return result; +} + +#endif /* CONFIG_COMPAT */