[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#728759: linux - compat_sys_getrlimit returns values compat_sys_setrlimit does not like



Control: tags -1 patch

On Tue, Nov 05, 2013 at 09:29:42AM +0100, Bastian Blank wrote:
> compat_sys_getrlimit clips all values above COMPAT_RLIM_INFINITY.  So
> any large values between COMPAT_RLIM_INFINITY and RLIM_INFINITY is
> returned as the same value COMPAT_RLIM_INFINITY.

Untested patch.  It converts COMPAT_RLIM_INFINITY <= x < RLIM_INFINITY
to COMPAT_RLIM_INFINITY - 1.  It would also work around the wrong
userspace definition on mips for anything that does not explicitely
request infinity (which would be broken anyway).

It assumes that COMPAT_RLIM_INFINITY <= RLIM_INFINITY.

Bastian

-- 
Conquest is easy. Control is not.
		-- Kirk, "Mirror, Mirror", stardate unknown
diff --git a/kernel/compat.c b/kernel/compat.c
index 0a09e48..7e5dfa7 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -478,10 +478,15 @@ asmlinkage long compat_sys_getrlimit(unsigned int resource,
 
 	ret = do_prlimit(current, resource, NULL, &r);
 	if (!ret) {
-		if (r.rlim_cur > COMPAT_RLIM_INFINITY)
+		if (r.rlim_cur == RLIM_INFINITY)
 			r.rlim_cur = COMPAT_RLIM_INFINITY;
-		if (r.rlim_max > COMPAT_RLIM_INFINITY)
+		else if (r.rlim_cur >= COMPAT_RLIM_INFINITY)
+			r.rlim_cur = COMPAT_RLIM_INFINITY - 1;
+
+		if (r.rlim_max == RLIM_INFINITY)
 			r.rlim_max = COMPAT_RLIM_INFINITY;
+		else if (r.rlim_max >= COMPAT_RLIM_INFINITY)
+			r.rlim_max = COMPAT_RLIM_INFINITY - 1;
 
 		if (!access_ok(VERIFY_WRITE, rlim, sizeof(*rlim)) ||
 		    __put_user(r.rlim_cur, &rlim->rlim_cur) ||

Reply to: