Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mm: security: Check early if HARDENED_USERCOPY is enabled

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>

authored by

Mel Gorman and committed by
Kees Cook
496d2d23 d2132f45

+15 -7
+8 -1
include/linux/ucopysize.h
··· 6 6 #include <linux/bug.h> 7 7 8 8 #ifdef CONFIG_HARDENED_USERCOPY 9 + #include <linux/jump_label.h> 9 10 extern void __check_object_size(const void *ptr, unsigned long n, 10 11 bool to_user); 12 + 13 + DECLARE_STATIC_KEY_MAYBE(CONFIG_HARDENED_USERCOPY_DEFAULT_ON, 14 + validate_usercopy_range); 11 15 12 16 static __always_inline void check_object_size(const void *ptr, unsigned long n, 13 17 bool to_user) 14 18 { 15 - if (!__builtin_constant_p(n)) 19 + if (!__builtin_constant_p(n) && 20 + static_branch_maybe(CONFIG_HARDENED_USERCOPY_DEFAULT_ON, 21 + &validate_usercopy_range)) { 16 22 __check_object_size(ptr, n, to_user); 23 + } 17 24 } 18 25 #else 19 26 static inline void check_object_size(const void *ptr, unsigned long n,
+7 -6
mm/usercopy.c
··· 201 201 } 202 202 } 203 203 204 - static DEFINE_STATIC_KEY_FALSE_RO(bypass_usercopy_checks); 204 + DEFINE_STATIC_KEY_MAYBE_RO(CONFIG_HARDENED_USERCOPY_DEFAULT_ON, 205 + validate_usercopy_range); 206 + EXPORT_SYMBOL(validate_usercopy_range); 205 207 206 208 /* 207 209 * Validates that the given object is: ··· 214 212 */ 215 213 void __check_object_size(const void *ptr, unsigned long n, bool to_user) 216 214 { 217 - if (static_branch_unlikely(&bypass_usercopy_checks)) 218 - return; 219 - 220 215 /* Skip all tests if size is zero. */ 221 216 if (!n) 222 217 return; ··· 269 270 270 271 static int __init set_hardened_usercopy(void) 271 272 { 272 - if (enable_checks == false) 273 - static_branch_enable(&bypass_usercopy_checks); 273 + if (enable_checks) 274 + static_branch_enable(&validate_usercopy_range); 275 + else 276 + static_branch_disable(&validate_usercopy_range); 274 277 return 1; 275 278 } 276 279