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.

uaccess: Introduce ucopysize.h

The object size sanity checking macros that uaccess.h and uio.h use
have been living in thread_info.h for historical reasons. Needing to
use jump labels for these checks, however, introduces a header include
loop under certain conditions. The dependencies for the object checking
macros are very limited, but they are used by separate header files,
so introduce a new header that can be used directly by uaccess.h and
uio.h. As a result, this also means thread_info.h (which is rather large)
and be removed from those headers.

Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202502281153.TG2XK5SI-lkp@intel.com/
Signed-off-by: Kees Cook <kees@kernel.org>

+60 -51
+1
MAINTAINERS
··· 12586 12586 F: arch/*/configs/hardening.config 12587 12587 F: include/linux/overflow.h 12588 12588 F: include/linux/randomize_kstack.h 12589 + F: include/linux/ucopysize.h 12589 12590 F: kernel/configs/hardening.config 12590 12591 F: lib/usercopy_kunit.c 12591 12592 F: mm/usercopy.c
-48
include/linux/thread_info.h
··· 217 217 } 218 218 #endif 219 219 220 - #ifdef CONFIG_HARDENED_USERCOPY 221 - extern void __check_object_size(const void *ptr, unsigned long n, 222 - bool to_user); 223 - 224 - static __always_inline void check_object_size(const void *ptr, unsigned long n, 225 - bool to_user) 226 - { 227 - if (!__builtin_constant_p(n)) 228 - __check_object_size(ptr, n, to_user); 229 - } 230 - #else 231 - static inline void check_object_size(const void *ptr, unsigned long n, 232 - bool to_user) 233 - { } 234 - #endif /* CONFIG_HARDENED_USERCOPY */ 235 - 236 - extern void __compiletime_error("copy source size is too small") 237 - __bad_copy_from(void); 238 - extern void __compiletime_error("copy destination size is too small") 239 - __bad_copy_to(void); 240 - 241 - void __copy_overflow(int size, unsigned long count); 242 - 243 - static inline void copy_overflow(int size, unsigned long count) 244 - { 245 - if (IS_ENABLED(CONFIG_BUG)) 246 - __copy_overflow(size, count); 247 - } 248 - 249 - static __always_inline __must_check bool 250 - check_copy_size(const void *addr, size_t bytes, bool is_source) 251 - { 252 - int sz = __builtin_object_size(addr, 0); 253 - if (unlikely(sz >= 0 && sz < bytes)) { 254 - if (!__builtin_constant_p(bytes)) 255 - copy_overflow(sz, bytes); 256 - else if (is_source) 257 - __bad_copy_from(); 258 - else 259 - __bad_copy_to(); 260 - return false; 261 - } 262 - if (WARN_ON_ONCE(bytes > INT_MAX)) 263 - return false; 264 - check_object_size(addr, bytes, is_source); 265 - return true; 266 - } 267 - 268 220 #ifndef arch_setup_new_exec 269 221 static inline void arch_setup_new_exec(void) { } 270 222 #endif
+1 -1
include/linux/uaccess.h
··· 7 7 #include <linux/minmax.h> 8 8 #include <linux/nospec.h> 9 9 #include <linux/sched.h> 10 - #include <linux/thread_info.h> 10 + #include <linux/ucopysize.h> 11 11 12 12 #include <asm/uaccess.h> 13 13
+56
include/linux/ucopysize.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* Perform sanity checking for object sizes for uaccess.h and uio.h. */ 3 + #ifndef __LINUX_UCOPYSIZE_H__ 4 + #define __LINUX_UCOPYSIZE_H__ 5 + 6 + #include <linux/bug.h> 7 + 8 + #ifdef CONFIG_HARDENED_USERCOPY 9 + extern void __check_object_size(const void *ptr, unsigned long n, 10 + bool to_user); 11 + 12 + static __always_inline void check_object_size(const void *ptr, unsigned long n, 13 + bool to_user) 14 + { 15 + if (!__builtin_constant_p(n)) 16 + __check_object_size(ptr, n, to_user); 17 + } 18 + #else 19 + static inline void check_object_size(const void *ptr, unsigned long n, 20 + bool to_user) 21 + { } 22 + #endif /* CONFIG_HARDENED_USERCOPY */ 23 + 24 + extern void __compiletime_error("copy source size is too small") 25 + __bad_copy_from(void); 26 + extern void __compiletime_error("copy destination size is too small") 27 + __bad_copy_to(void); 28 + 29 + void __copy_overflow(int size, unsigned long count); 30 + 31 + static inline void copy_overflow(int size, unsigned long count) 32 + { 33 + if (IS_ENABLED(CONFIG_BUG)) 34 + __copy_overflow(size, count); 35 + } 36 + 37 + static __always_inline __must_check bool 38 + check_copy_size(const void *addr, size_t bytes, bool is_source) 39 + { 40 + int sz = __builtin_object_size(addr, 0); 41 + if (unlikely(sz >= 0 && sz < bytes)) { 42 + if (!__builtin_constant_p(bytes)) 43 + copy_overflow(sz, bytes); 44 + else if (is_source) 45 + __bad_copy_from(); 46 + else 47 + __bad_copy_to(); 48 + return false; 49 + } 50 + if (WARN_ON_ONCE(bytes > INT_MAX)) 51 + return false; 52 + check_object_size(addr, bytes, is_source); 53 + return true; 54 + } 55 + 56 + #endif /* __LINUX_UCOPYSIZE_H__ */
+1 -1
include/linux/uio.h
··· 6 6 #define __LINUX_UIO_H 7 7 8 8 #include <linux/kernel.h> 9 - #include <linux/thread_info.h> 10 9 #include <linux/mm_types.h> 10 + #include <linux/ucopysize.h> 11 11 #include <uapi/linux/uio.h> 12 12 13 13 struct page;
+1 -1
mm/usercopy.c
··· 17 17 #include <linux/sched.h> 18 18 #include <linux/sched/task.h> 19 19 #include <linux/sched/task_stack.h> 20 - #include <linux/thread_info.h> 20 + #include <linux/ucopysize.h> 21 21 #include <linux/vmalloc.h> 22 22 #include <linux/atomic.h> 23 23 #include <linux/jump_label.h>