]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
mm: security: Check early if HARDENED_USERCOPY is enabled
authorMel Gorman <mgorman@techsingularity.net>
Thu, 23 Jan 2025 22:11:14 +0000 (22:11 +0000)
committerKees Cook <kees@kernel.org>
Fri, 28 Feb 2025 19:51:31 +0000 (11:51 -0800)
HARDENED_USERCOPY is checked within a function so even if disabled, the
function overhead still exists. Move the static check inline.

This is at best a micro-optimisation and any difference in performance
was within noise but it is relatively consistent with the init_on_*
implementations.

Suggested-by: Kees Cook <kees@kernel.org>
Signed-off-by: Mel Gorman <mgorman@techsingularity.net>
Link: https://lore.kernel.org/r/20250123221115.19722-4-mgorman@techsingularity.net
Signed-off-by: Kees Cook <kees@kernel.org>
include/linux/ucopysize.h
mm/usercopy.c

index b3e1b875d5658d06aea98878a6b128908b920e9a..41c2d9720466b92961af5b5d578eff5eee0c5b66 100644 (file)
@@ -6,14 +6,21 @@
 #include <linux/bug.h>
 
 #ifdef CONFIG_HARDENED_USERCOPY
+#include <linux/jump_label.h>
 extern void __check_object_size(const void *ptr, unsigned long n,
                                        bool to_user);
 
+DECLARE_STATIC_KEY_MAYBE(CONFIG_HARDENED_USERCOPY_DEFAULT_ON,
+                          validate_usercopy_range);
+
 static __always_inline void check_object_size(const void *ptr, unsigned long n,
                                              bool to_user)
 {
-       if (!__builtin_constant_p(n))
+       if (!__builtin_constant_p(n) &&
+           static_branch_maybe(CONFIG_HARDENED_USERCOPY_DEFAULT_ON,
+                               &validate_usercopy_range)) {
                __check_object_size(ptr, n, to_user);
+       }
 }
 #else
 static inline void check_object_size(const void *ptr, unsigned long n,
index e65a612ce8e8742c83dd07fb76cd6f61b40afd57..dbdcc43964fb1ca97842f1dbc9cf587adcb121c3 100644 (file)
@@ -201,7 +201,9 @@ static inline void check_heap_object(const void *ptr, unsigned long n,
        }
 }
 
-static DEFINE_STATIC_KEY_FALSE_RO(bypass_usercopy_checks);
+DEFINE_STATIC_KEY_MAYBE_RO(CONFIG_HARDENED_USERCOPY_DEFAULT_ON,
+                          validate_usercopy_range);
+EXPORT_SYMBOL(validate_usercopy_range);
 
 /*
  * Validates that the given object is:
@@ -212,9 +214,6 @@ static DEFINE_STATIC_KEY_FALSE_RO(bypass_usercopy_checks);
  */
 void __check_object_size(const void *ptr, unsigned long n, bool to_user)
 {
-       if (static_branch_unlikely(&bypass_usercopy_checks))
-               return;
-
        /* Skip all tests if size is zero. */
        if (!n)
                return;
@@ -270,8 +269,10 @@ __setup("hardened_usercopy=", parse_hardened_usercopy);
 
 static int __init set_hardened_usercopy(void)
 {
-       if (enable_checks == false)
-               static_branch_enable(&bypass_usercopy_checks);
+       if (enable_checks)
+               static_branch_enable(&validate_usercopy_range);
+       else
+               static_branch_disable(&validate_usercopy_range);
        return 1;
 }