]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
usercopy: Enhance and rename report_usercopy()
authorKees Cook <keescook@chromium.org>
Wed, 10 Jan 2018 22:22:38 +0000 (14:22 -0800)
committerKees Cook <keescook@chromium.org>
Mon, 15 Jan 2018 20:07:44 +0000 (12:07 -0800)
In preparation for refactoring the usercopy checks to pass offset to
the hardened usercopy report, this renames report_usercopy() to the
more accurate usercopy_abort(), marks it as noreturn because it is,
adds a hopefully helpful comment for anyone investigating such reports,
makes the function available to the slab allocators, and adds new "detail"
and "offset" arguments.

Signed-off-by: Kees Cook <keescook@chromium.org>
include/linux/uaccess.h
mm/usercopy.c
tools/objtool/check.c

index 251e655d407fadfb43f604c032c2b026a9a1fc38..38b6442dc5695433012df91b752073f039c3b846 100644 (file)
@@ -273,4 +273,10 @@ extern long strncpy_from_unsafe(char *dst, const void *unsafe_addr, long count);
 #define unsafe_put_user(x, ptr, err) do { if (unlikely(__put_user(x, ptr))) goto err; } while (0)
 #endif
 
+#ifdef CONFIG_HARDENED_USERCOPY
+void __noreturn usercopy_abort(const char *name, const char *detail,
+                              bool to_user, unsigned long offset,
+                              unsigned long len);
+#endif
+
 #endif         /* __LINUX_UACCESS_H__ */
index 5df1e68d45857c322d49dae511f69f8f6e337c40..8006baa4caacf65a3299fc7ac8d3562de195068b 100644 (file)
@@ -58,11 +58,25 @@ static noinline int check_stack_object(const void *obj, unsigned long len)
        return GOOD_STACK;
 }
 
-static void report_usercopy(unsigned long len, bool to_user, const char *type)
+/*
+ * If this function is reached, then CONFIG_HARDENED_USERCOPY has found an
+ * unexpected state during a copy_from_user() or copy_to_user() call.
+ * There are several checks being performed on the buffer by the
+ * __check_object_size() function. Normal stack buffer usage should never
+ * trip the checks, and kernel text addressing will always trip the check.
+ * For cache objects, copies must be within the object size.
+ */
+void __noreturn usercopy_abort(const char *name, const char *detail,
+                              bool to_user, unsigned long offset,
+                              unsigned long len)
 {
-       pr_emerg("kernel memory %s attempt detected %s '%s' (%lu bytes)\n",
-               to_user ? "exposure" : "overwrite",
-               to_user ? "from" : "to", type ? : "unknown", len);
+       pr_emerg("Kernel memory %s attempt detected %s %s%s%s%s (offset %lu, size %lu)!\n",
+                to_user ? "exposure" : "overwrite",
+                to_user ? "from" : "to",
+                name ? : "unknown?!",
+                detail ? " '" : "", detail ? : "", detail ? "'" : "",
+                offset, len);
+
        /*
         * For greater effect, it would be nice to do do_group_exit(),
         * but BUG() actually hooks all the lock-breaking and per-arch
@@ -260,6 +274,6 @@ void __check_object_size(const void *ptr, unsigned long n, bool to_user)
                return;
 
 report:
-       report_usercopy(n, to_user, err);
+       usercopy_abort(err, NULL, to_user, 0, n);
 }
 EXPORT_SYMBOL(__check_object_size);
index 9b341584eb1b56b05761bea127ee6cf94eacc190..ae39444896d4d15c79745a3c9e5eace2bd1c9434 100644 (file)
@@ -138,6 +138,7 @@ static int __dead_end_function(struct objtool_file *file, struct symbol *func,
                "__reiserfs_panic",
                "lbug_with_loc",
                "fortify_panic",
+               "usercopy_abort",
        };
 
        if (func->bind == STB_WEAK)