[S390] uaccess: implement strict user copy checks
authorHeiko Carstens <heiko.carstens@de.ibm.com>
Fri, 26 Feb 2010 21:37:22 +0000 (22:37 +0100)
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>
Fri, 26 Feb 2010 21:37:29 +0000 (22:37 +0100)
Same as on x86 and sparc, besides the fact that enabling the option
will just emit compile time warnings instead of errors.
Keeps allyesconfig kernels compiling.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/Kconfig.debug
arch/s390/include/asm/uaccess.h
arch/s390/lib/Makefile
arch/s390/lib/usercopy.c [new file with mode: 0644]

index 2283933..45e0c61 100644 (file)
@@ -6,4 +6,17 @@ config TRACE_IRQFLAGS_SUPPORT
 
 source "lib/Kconfig.debug"
 
+config DEBUG_STRICT_USER_COPY_CHECKS
+       bool "Strict user copy size checks"
+       ---help---
+         Enabling this option turns a certain set of sanity checks for user
+         copy operations into compile time warnings.
+
+         The copy_from_user() etc checks are there to help test if there
+         are sufficient security checks on the length argument of
+         the copy operation, by having gcc prove that the argument is
+         within bounds.
+
+         If unsure, or if you run an older (pre 4.4) gcc, say N.
+
 endmenu
index cbf0a87..d6b1ed0 100644 (file)
@@ -265,6 +265,12 @@ __copy_from_user(void *to, const void __user *from, unsigned long n)
                return uaccess.copy_from_user(n, from, to);
 }
 
+extern void copy_from_user_overflow(void)
+#ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS
+__compiletime_warning("copy_from_user() buffer size is not provably correct")
+#endif
+;
+
 /**
  * copy_from_user: - Copy a block of data from user space.
  * @to:   Destination address, in kernel space.
@@ -284,7 +290,13 @@ __copy_from_user(void *to, const void __user *from, unsigned long n)
 static inline unsigned long __must_check
 copy_from_user(void *to, const void __user *from, unsigned long n)
 {
+       unsigned int sz = __compiletime_object_size(to);
+
        might_fault();
+       if (unlikely(sz != -1 && sz < n)) {
+               copy_from_user_overflow();
+               return n;
+       }
        if (access_ok(VERIFY_READ, from, n))
                n = __copy_from_user(to, from, n);
        else
index 97975ec..cd54a1c 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for s390-specific library files..
 #
 
-lib-y += delay.o string.o uaccess_std.o uaccess_pt.o
+lib-y += delay.o string.o uaccess_std.o uaccess_pt.o usercopy.o
 obj-$(CONFIG_32BIT) += div64.o qrnnd.o ucmpdi2.o
 lib-$(CONFIG_64BIT) += uaccess_mvcos.o
 lib-$(CONFIG_SMP) += spinlock.o
diff --git a/arch/s390/lib/usercopy.c b/arch/s390/lib/usercopy.c
new file mode 100644 (file)
index 0000000..14b363f
--- /dev/null
@@ -0,0 +1,8 @@
+#include <linux/module.h>
+#include <linux/bug.h>
+
+void copy_from_user_overflow(void)
+{
+       WARN(1, "Buffer overflow detected!\n");
+}
+EXPORT_SYMBOL(copy_from_user_overflow);