]> Gentwo Git Trees - linux/.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>
Wed, 12 Feb 2025 21:40:17 +0000 (13:40 -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/thread_info.h
mm/usercopy.c

index cf2446c9c30d443de5235f27b160c00cc06a8050..439a707fea9d2dd7092d4d6a4b6d9513f7c6fe05 100644 (file)
@@ -218,14 +218,21 @@ static inline int arch_within_stack_frames(const void * const stack,
 #endif
 
 #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 4cf33305347a5bbfd3eedbbe36d5fe7cc2f37f3a..a1193bdabb16baceb47b4c1cb831cb87cd03a391 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;
 }