Merge branch 'kvm-updates/2.6.36' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[pandora-kernel.git] / kernel / compat.c
index 5adab05..c9e2ec0 100644 (file)
@@ -279,11 +279,6 @@ asmlinkage long compat_sys_setrlimit(unsigned int resource,
                struct compat_rlimit __user *rlim)
 {
        struct rlimit r;
-       int ret;
-       mm_segment_t old_fs = get_fs ();
-
-       if (resource >= RLIM_NLIMITS)
-               return -EINVAL;
 
        if (!access_ok(VERIFY_READ, rlim, sizeof(*rlim)) ||
            __get_user(r.rlim_cur, &rlim->rlim_cur) ||
@@ -294,10 +289,7 @@ asmlinkage long compat_sys_setrlimit(unsigned int resource,
                r.rlim_cur = RLIM_INFINITY;
        if (r.rlim_max == COMPAT_RLIM_INFINITY)
                r.rlim_max = RLIM_INFINITY;
-       set_fs(KERNEL_DS);
-       ret = sys_setrlimit(resource, (struct rlimit __user *) &r);
-       set_fs(old_fs);
-       return ret;
+       return do_prlimit(current, resource, &r, NULL);
 }
 
 #ifdef COMPAT_RLIM_OLD_INFINITY
@@ -329,16 +321,13 @@ asmlinkage long compat_sys_old_getrlimit(unsigned int resource,
 
 #endif
 
-asmlinkage long compat_sys_getrlimit (unsigned int resource,
+asmlinkage long compat_sys_getrlimit(unsigned int resource,
                struct compat_rlimit __user *rlim)
 {
        struct rlimit r;
        int ret;
-       mm_segment_t old_fs = get_fs();
 
-       set_fs(KERNEL_DS);
-       ret = sys_getrlimit(resource, (struct rlimit __user *) &r);
-       set_fs(old_fs);
+       ret = do_prlimit(current, resource, NULL, &r);
        if (!ret) {
                if (r.rlim_cur > COMPAT_RLIM_INFINITY)
                        r.rlim_cur = COMPAT_RLIM_INFINITY;
@@ -1137,3 +1126,24 @@ compat_sys_sysinfo(struct compat_sysinfo __user *info)
 
        return 0;
 }
+
+/*
+ * Allocate user-space memory for the duration of a single system call,
+ * in order to marshall parameters inside a compat thunk.
+ */
+void __user *compat_alloc_user_space(unsigned long len)
+{
+       void __user *ptr;
+
+       /* If len would occupy more than half of the entire compat space... */
+       if (unlikely(len > (((compat_uptr_t)~0) >> 1)))
+               return NULL;
+
+       ptr = arch_compat_alloc_user_space(len);
+
+       if (unlikely(!access_ok(VERIFY_WRITE, ptr, len)))
+               return NULL;
+
+       return ptr;
+}
+EXPORT_SYMBOL_GPL(compat_alloc_user_space);