diff options
Diffstat (limited to 'kernel/compat.c')
| -rw-r--r-- | kernel/compat.c | 38 | 
1 files changed, 24 insertions, 14 deletions
| diff --git a/kernel/compat.c b/kernel/compat.c index 5adab05a317..c9e2ec0b34a 100644 --- a/kernel/compat.c +++ b/kernel/compat.c @@ -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); | 
