summaryrefslogtreecommitdiffstats
path: root/mm/usercopy.c
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2018-01-10 14:22:38 -0800
committerKees Cook <keescook@chromium.org>2018-01-15 12:07:44 -0800
commitb394d468e7d75637e682a9be4a1181b27186c593 (patch)
tree1c0894b3aafc06a4ee6bfc6facc81d192781de66 /mm/usercopy.c
parent4f5e838605c264fcf16c3ff9495bd83da99acc6a (diff)
downloadlinux-b394d468e7d75637e682a9be4a1181b27186c593.tar.gz
linux-b394d468e7d75637e682a9be4a1181b27186c593.tar.bz2
linux-b394d468e7d75637e682a9be4a1181b27186c593.zip
usercopy: Enhance and rename report_usercopy()
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>
Diffstat (limited to 'mm/usercopy.c')
-rw-r--r--mm/usercopy.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/mm/usercopy.c b/mm/usercopy.c
index 5df1e68d4585..8006baa4caac 100644
--- a/mm/usercopy.c
+++ b/mm/usercopy.c
@@ -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);