Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1501757

[PATCH 3.12 17/84] fix fault_in_multipages_...() on architectures with no-op access_ok()

From Jiri Slaby <jslaby@suse.cz>
Newsgroups linux.kernel
Subject [PATCH 3.12 17/84] fix fault_in_multipages_...() on architectures with no-op access_ok()
Date 2016-10-17 10:30 +0200
Message-ID <stbsZ-12r-1@gated-at.bofh.it> (permalink)
References <staZY-A3-7@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


From: Al Viro <viro@ZenIV.linux.org.uk>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit e23d4159b109167126e5bcd7f3775c95de7fee47 upstream.

Switching iov_iter fault-in to multipages variants has exposed an old
bug in underlying fault_in_multipages_...(); they break if the range
passed to them wraps around.  Normally access_ok() done by callers will
prevent such (and it's a guaranteed EFAULT - ERR_PTR() values fall into
such a range and they should not point to any valid objects).

However, on architectures where userland and kernel live in different
MMU contexts (e.g. s390) access_ok() is a no-op and on those a range
with a wraparound can reach fault_in_multipages_...().

Since any wraparound means EFAULT there, the fix is trivial - turn
those

    while (uaddr <= end)
	    ...
into

    if (unlikely(uaddr > end))
	    return -EFAULT;
    do
	    ...
    while (uaddr <= end);

Reported-by: Jan Stancek <jstancek@redhat.com>
Tested-by: Jan Stancek <jstancek@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 include/linux/pagemap.h | 38 +++++++++++++++++++-------------------
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index bf944e86895b..db958a33caf1 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -574,56 +574,56 @@ static inline int fault_in_pages_readable(const char __user *uaddr, int size)
  */
 static inline int fault_in_multipages_writeable(char __user *uaddr, int size)
 {
-	int ret = 0;
 	char __user *end = uaddr + size - 1;
 
 	if (unlikely(size == 0))
-		return ret;
+		return 0;
 
+	if (unlikely(uaddr > end))
+		return -EFAULT;
 	/*
 	 * Writing zeroes into userspace here is OK, because we know that if
 	 * the zero gets there, we'll be overwriting it.
 	 */
-	while (uaddr <= end) {
-		ret = __put_user(0, uaddr);
-		if (ret != 0)
-			return ret;
+	do {
+		if (unlikely(__put_user(0, uaddr) != 0))
+			return -EFAULT;
 		uaddr += PAGE_SIZE;
-	}
+	} while (uaddr <= end);
 
 	/* Check whether the range spilled into the next page. */
 	if (((unsigned long)uaddr & PAGE_MASK) ==
 			((unsigned long)end & PAGE_MASK))
-		ret = __put_user(0, end);
+		return __put_user(0, end);
 
-	return ret;
+	return 0;
 }
 
 static inline int fault_in_multipages_readable(const char __user *uaddr,
 					       int size)
 {
 	volatile char c;
-	int ret = 0;
 	const char __user *end = uaddr + size - 1;
 
 	if (unlikely(size == 0))
-		return ret;
+		return 0;
 
-	while (uaddr <= end) {
-		ret = __get_user(c, uaddr);
-		if (ret != 0)
-			return ret;
+	if (unlikely(uaddr > end))
+		return -EFAULT;
+
+	do {
+		if (unlikely(__get_user(c, uaddr) != 0))
+			return -EFAULT;
 		uaddr += PAGE_SIZE;
-	}
+	} while (uaddr <= end);
 
 	/* Check whether the range spilled into the next page. */
 	if (((unsigned long)uaddr & PAGE_MASK) ==
 			((unsigned long)end & PAGE_MASK)) {
-		ret = __get_user(c, end);
-		(void)c;
+		return __get_user(c, end);
 	}
 
-	return ret;
+	return 0;
 }
 
 int add_to_page_cache_locked(struct page *page, struct address_space *mapping,
-- 
2.10.1

Back to linux.kernel | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

[PATCH 3.12 00/84] 3.12.65-stable review Jiri Slaby <jslaby@suse.cz> - 2016-10-17 10:10 +0200
  [PATCH 3.12 01/84] gcov: disable tree-loop-im to reduce stack usage Jiri Slaby <jslaby@suse.cz> - 2016-10-17 10:20 +0200
    [PATCH 3.12 43/84] drm/radeon/si/dpm: add workaround for for Jet parts Jiri Slaby <jslaby@suse.cz> - 2016-10-17 10:20 +0200
    [PATCH 3.12 17/84] fix fault_in_multipages_...() on architectures with no-op access_ok() Jiri Slaby <jslaby@suse.cz> - 2016-10-17 10:30 +0200
    [PATCH 3.12 11/84] Disable "maybe-uninitialized" warning globally Jiri Slaby <jslaby@suse.cz> - 2016-10-17 10:30 +0200
    [PATCH 3.12 13/84] Makefile: Mute warning for __builtin_return_address(>0) for tracing only Jiri Slaby <jslaby@suse.cz> - 2016-10-17 10:30 +0200
    [PATCH 3.12 20/84] tracing: Move mutex to protect against resetting of seq data Jiri Slaby <jslaby@suse.cz> - 2016-10-17 10:30 +0200
    [PATCH 3.12 18/84] mtd: pmcmsp-flash: Allocating too much in init_msp_flash() Jiri Slaby <jslaby@suse.cz> - 2016-10-17 10:30 +0200
    [PATCH 3.12 12/84] Disable "frame-address" warning Jiri Slaby <jslaby@suse.cz> - 2016-10-17 10:30 +0200
    [PATCH 3.12 15/84] iwlegacy: avoid warning about missing braces Jiri Slaby <jslaby@suse.cz> - 2016-10-17 10:30 +0200
    [PATCH 3.12 14/84] net: caif: fix misleading indentation Jiri Slaby <jslaby@suse.cz> - 2016-10-17 10:30 +0200
  Re: [PATCH 3.12 00/84] 3.12.65-stable review Guenter Roeck <linux@roeck-us.net> - 2016-10-17 20:40 +0200
  Re: [PATCH 3.12 00/84] 3.12.65-stable review Shuah Khan <shuah.kh@samsung.com> - 2016-10-18 00:20 +0200

csiph-web