s390/uaccess: fix strncpy_from_user/strnlen_user zero maxlen case
authorHeiko Carstens <heiko.carstens@de.ibm.com>
Thu, 21 Feb 2013 12:30:42 +0000 (13:30 +0100)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Thu, 28 Feb 2013 08:37:08 +0000 (09:37 +0100)
If the maximum length specified for the to be accessed string for
strncpy_from_user() and strnlen_user() is zero the following incorrect
values would be returned or incorrect memory accesses would happen:

strnlen_user_std() and strnlen_user_pt() incorrectly return "1"
strncpy_from_user_pt() would incorrectly access "dst[maxlen - 1]"
strncpy_from_user_mvcos() would incorrectly return "-EFAULT"

Fix all these oddities by adding early checks.

Reviewed-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/lib/uaccess_mvcos.c
arch/s390/lib/uaccess_pt.c
arch/s390/lib/uaccess_std.c

index 7f3eb3d5602414158b169c3ba195d4ce178448bb..1829742bf4793fae0060dbb4bd31b4e0bfbacc4f 100644 (file)
@@ -184,6 +184,8 @@ static size_t strncpy_from_user_mvcos(size_t count, const char __user *src,
 {
        size_t done, len, offset, len_str;
 
+       if (unlikely(!count))
+               return 0;
        done = 0;
        do {
                offset = (size_t)src & ~PAGE_MASK;
index a70ee84c024126ca562f8d738b52a590e4fd6a2b..c1aaf22c326b6d2b09a0a4265a999832f58179a5 100644 (file)
@@ -172,6 +172,8 @@ static size_t strnlen_user_pt(size_t count, const char __user *src)
        unsigned long offset, done, len, kaddr;
        size_t len_str;
 
+       if (unlikely(!count))
+               return 0;
        if (segment_eq(get_fs(), KERNEL_DS))
                return strnlen((const char __kernel __force *) src, count) + 1;
        done = 0;
@@ -202,6 +204,8 @@ static size_t strncpy_from_user_pt(size_t count, const char __user *src,
 {
        size_t n = strnlen_user_pt(count, src);
 
+       if (unlikely(!count))
+               return 0;
        if (!n)
                return -EFAULT;
        if (n > count)
index 6fbd063382709f7ec3a9a0ca2fafbaa0cf72dd86..79c6c7d76e08e7174e188d3ffcabec9b627480fc 100644 (file)
@@ -188,6 +188,8 @@ size_t strnlen_user_std(size_t size, const char __user *src)
        register unsigned long reg0 asm("0") = 0UL;
        unsigned long tmp1, tmp2;
 
+       if (unlikely(!size))
+               return 0;
        asm volatile(
                "   la    %2,0(%1)\n"
                "   la    %3,0(%0,%1)\n"
This page took 0.027407 seconds and 5 git commands to generate.