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.

Merge tag 'hardening-v7.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux

Pull hardening updates from Kees Cook:

- randomize_kstack: Improve implementation across arches (Ryan Roberts)

- lkdtm/fortify: Drop unneeded FORTIFY_STR_OBJECT test

- refcount: Remove unused __signed_wrap function annotations

* tag 'hardening-v7.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
lkdtm/fortify: Drop unneeded FORTIFY_STR_OBJECT test
refcount: Remove unused __signed_wrap function annotations
randomize_kstack: Unify random source across arches
randomize_kstack: Maintain kstack_offset per task

+49 -154
+2 -3
arch/Kconfig
··· 1518 1518 def_bool n 1519 1519 help 1520 1520 An arch should select this symbol if it can support kernel stack 1521 - offset randomization with calls to add_random_kstack_offset() 1522 - during syscall entry and choose_random_kstack_offset() during 1523 - syscall exit. Careful removal of -fstack-protector-strong and 1521 + offset randomization with a call to add_random_kstack_offset() 1522 + during syscall entry. Careful removal of -fstack-protector-strong and 1524 1523 -fstack-protector should also be applied to the entry code and 1525 1524 closely examined, as the artificial stack bump looks like an array 1526 1525 to the compiler, so it will attempt to add canary checks regardless
-11
arch/arm64/kernel/syscall.c
··· 52 52 } 53 53 54 54 syscall_set_return_value(current, regs, 0, ret); 55 - 56 - /* 57 - * This value will get limited by KSTACK_OFFSET_MAX(), which is 10 58 - * bits. The actual entropy will be further reduced by the compiler 59 - * when applying stack alignment constraints: the AAPCS mandates a 60 - * 16-byte aligned SP at function boundaries, which will remove the 61 - * 4 low bits from any entropy chosen here. 62 - * 63 - * The resulting 6 bits of entropy is seen in SP[9:4]. 64 - */ 65 - choose_random_kstack_offset(get_random_u16()); 66 55 } 67 56 68 57 static inline bool has_syscall_work(unsigned long flags)
-11
arch/loongarch/kernel/syscall.c
··· 79 79 regs->regs[7], regs->regs[8], regs->regs[9]); 80 80 } 81 81 82 - /* 83 - * This value will get limited by KSTACK_OFFSET_MAX(), which is 10 84 - * bits. The actual entropy will be further reduced by the compiler 85 - * when applying stack alignment constraints: 16-bytes (i.e. 4-bits) 86 - * aligned, which will remove the 4 low bits from any entropy chosen 87 - * here. 88 - * 89 - * The resulting 6 bits of entropy is seen in SP[9:4]. 90 - */ 91 - choose_random_kstack_offset(get_cycles()); 92 - 93 82 syscall_exit_to_user_mode(regs); 94 83 }
+2 -14
arch/powerpc/kernel/syscall.c
··· 20 20 21 21 kuap_lock(); 22 22 23 - add_random_kstack_offset(); 24 - 25 23 if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) 26 24 BUG_ON(irq_soft_mask_return() != IRQS_ALL_DISABLED); 27 25 ··· 27 29 28 30 CT_WARN_ON(ct_state() == CT_STATE_KERNEL); 29 31 user_exit_irqoff(); 32 + 33 + add_random_kstack_offset(); 30 34 31 35 BUG_ON(regs_is_unrecoverable(regs)); 32 36 BUG_ON(!user_mode(regs)); ··· 172 172 regs->gpr[6], regs->gpr[7], regs->gpr[8]); 173 173 } 174 174 #endif 175 - 176 - /* 177 - * Ultimately, this value will get limited by KSTACK_OFFSET_MAX(), 178 - * so the maximum stack offset is 1k bytes (10 bits). 179 - * 180 - * The actual entropy will be further reduced by the compiler when 181 - * applying stack alignment constraints: the powerpc architecture 182 - * may have two kinds of stack alignment (16-bytes and 8-bytes). 183 - * 184 - * So the resulting 6 or 7 bits of entropy is seen in SP[9:4] or SP[9:3]. 185 - */ 186 - choose_random_kstack_offset(mftb()); 187 175 188 176 return ret; 189 177 }
-12
arch/riscv/kernel/traps.c
··· 344 344 syscall_handler(regs, syscall); 345 345 } 346 346 347 - /* 348 - * Ultimately, this value will get limited by KSTACK_OFFSET_MAX(), 349 - * so the maximum stack offset is 1k bytes (10 bits). 350 - * 351 - * The actual entropy will be further reduced by the compiler when 352 - * applying stack alignment constraints: 16-byte (i.e. 4-bit) aligned 353 - * for RV32I or RV64I. 354 - * 355 - * The resulting 6 bits of entropy is seen in SP[9:4]. 356 - */ 357 - choose_random_kstack_offset(get_random_u16()); 358 - 359 347 syscall_exit_to_user_mode(regs); 360 348 } else { 361 349 irqentry_state_t state = irqentry_nmi_enter(regs);
-8
arch/s390/include/asm/entry-common.h
··· 51 51 52 52 #define arch_exit_to_user_mode arch_exit_to_user_mode 53 53 54 - static inline void arch_exit_to_user_mode_prepare(struct pt_regs *regs, 55 - unsigned long ti_work) 56 - { 57 - choose_random_kstack_offset(get_tod_clock_fast()); 58 - } 59 - 60 - #define arch_exit_to_user_mode_prepare arch_exit_to_user_mode_prepare 61 - 62 54 static __always_inline bool arch_in_rcu_eqs(void) 63 55 { 64 56 if (IS_ENABLED(CONFIG_KVM))
+1 -1
arch/s390/kernel/syscall.c
··· 97 97 { 98 98 unsigned long nr; 99 99 100 - add_random_kstack_offset(); 101 100 enter_from_user_mode(regs); 101 + add_random_kstack_offset(); 102 102 regs->psw = get_lowcore()->svc_old_psw; 103 103 regs->int_code = get_lowcore()->svc_int_code; 104 104 update_timer_sys();
+2 -2
arch/x86/entry/syscall_32.c
··· 247 247 { 248 248 int nr = syscall_32_enter(regs); 249 249 250 - add_random_kstack_offset(); 251 250 /* 252 251 * Subtlety here: if ptrace pokes something larger than 2^31-1 into 253 252 * orig_ax, the int return value truncates it. This matches ··· 255 256 nr = syscall_enter_from_user_mode(regs, nr); 256 257 instrumentation_begin(); 257 258 259 + add_random_kstack_offset(); 258 260 do_syscall_32_irqs_on(regs, nr); 259 261 260 262 instrumentation_end(); ··· 268 268 int nr = syscall_32_enter(regs); 269 269 int res; 270 270 271 - add_random_kstack_offset(); 272 271 /* 273 272 * This cannot use syscall_enter_from_user_mode() as it has to 274 273 * fetch EBP before invoking any of the syscall entry work ··· 276 277 enter_from_user_mode(regs); 277 278 278 279 instrumentation_begin(); 280 + add_random_kstack_offset(); 279 281 local_irq_enable(); 280 282 /* Fetch EBP from where the vDSO stashed it. */ 281 283 if (IS_ENABLED(CONFIG_X86_64)) {
+1 -1
arch/x86/entry/syscall_64.c
··· 86 86 /* Returns true to return using SYSRET, or false to use IRET */ 87 87 __visible noinstr bool do_syscall_64(struct pt_regs *regs, int nr) 88 88 { 89 - add_random_kstack_offset(); 90 89 nr = syscall_enter_from_user_mode(regs, nr); 91 90 92 91 instrumentation_begin(); 92 + add_random_kstack_offset(); 93 93 94 94 if (!do_syscall_x64(regs, nr) && !do_syscall_x32(regs, nr) && nr != -1) { 95 95 /* Invalid system call, but still a system call. */
-12
arch/x86/include/asm/entry-common.h
··· 82 82 current_thread_info()->status &= ~(TS_COMPAT | TS_I386_REGS_POKED); 83 83 #endif 84 84 85 - /* 86 - * This value will get limited by KSTACK_OFFSET_MAX(), which is 10 87 - * bits. The actual entropy will be further reduced by the compiler 88 - * when applying stack alignment constraints (see cc_stack_align4/8 in 89 - * arch/x86/Makefile), which will remove the 3 (x86_64) or 2 (ia32) 90 - * low bits from any entropy chosen here. 91 - * 92 - * Therefore, final stack offset entropy will be 7 (x86_64) or 93 - * 8 (ia32) bits. 94 - */ 95 - choose_random_kstack_offset(rdtsc()); 96 - 97 85 /* Avoid unnecessary reads of 'x86_ibpb_exit_to_user' */ 98 86 if (cpu_feature_enabled(X86_FEATURE_IBPB_EXIT_TO_USER) && 99 87 this_cpu_read(x86_ibpb_exit_to_user)) {
+6 -30
drivers/misc/lkdtm/fortify.c
··· 10 10 11 11 static volatile int fortify_scratch_space; 12 12 13 - static void lkdtm_FORTIFY_STR_OBJECT(void) 14 - { 15 - struct target { 16 - char a[10]; 17 - int foo; 18 - } target[3] = {}; 19 - /* 20 - * Using volatile prevents the compiler from determining the value of 21 - * 'size' at compile time. Without that, we would get a compile error 22 - * rather than a runtime error. 23 - */ 24 - volatile int size = 20; 25 - 26 - pr_info("trying to strcmp() past the end of a struct\n"); 27 - 28 - strncpy(target[0].a, target[1].a, size); 29 - 30 - /* Store result to global to prevent the code from being eliminated */ 31 - fortify_scratch_space = target[0].a[3]; 32 - 33 - pr_err("FAIL: fortify did not block a strncpy() object write overflow!\n"); 34 - pr_expected_config(CONFIG_FORTIFY_SOURCE); 35 - } 36 - 37 13 static void lkdtm_FORTIFY_STR_MEMBER(void) 38 14 { 39 15 struct target { ··· 23 47 if (!src) 24 48 return; 25 49 50 + /* 15 bytes: past end of a[] but not target. */ 26 51 strscpy(src, "over ten bytes", size); 27 52 size = strlen(src) + 1; 28 53 29 - pr_info("trying to strncpy() past the end of a struct member...\n"); 54 + pr_info("trying to strscpy() past the end of a struct member...\n"); 30 55 31 56 /* 32 - * strncpy(target.a, src, 20); will hit a compile error because the 33 - * compiler knows at build time that target.a < 20 bytes. Use a 57 + * strscpy(target.a, src, 15); will hit a compile error because the 58 + * compiler knows at build time that target.a < 15 bytes. Use a 34 59 * volatile to force a runtime error. 35 60 */ 36 - strncpy(target.a, src, size); 61 + strscpy(target.a, src, size); 37 62 38 63 /* Store result to global to prevent the code from being eliminated */ 39 64 fortify_scratch_space = target.a[3]; 40 65 41 - pr_err("FAIL: fortify did not block a strncpy() struct member write overflow!\n"); 66 + pr_err("FAIL: fortify did not block a strscpy() struct member write overflow!\n"); 42 67 pr_expected_config(CONFIG_FORTIFY_SOURCE); 43 68 44 69 kfree(src); ··· 187 210 } 188 211 189 212 static struct crashtype crashtypes[] = { 190 - CRASHTYPE(FORTIFY_STR_OBJECT), 191 213 CRASHTYPE(FORTIFY_STR_MEMBER), 192 214 CRASHTYPE(FORTIFY_MEM_OBJECT), 193 215 CRASHTYPE(FORTIFY_MEM_MEMBER),
+1 -8
include/linux/compiler_types.h
··· 432 432 #define at_least 433 433 #endif 434 434 435 - /* Do not trap wrapping arithmetic within an annotated function. */ 436 - #ifdef CONFIG_UBSAN_INTEGER_WRAP 437 - # define __signed_wrap __attribute__((no_sanitize("signed-integer-overflow"))) 438 - #else 439 - # define __signed_wrap 440 - #endif 441 - 442 435 /* Section for code which can't be instrumented at all */ 443 436 #define __noinstr_section(section) \ 444 437 noinline notrace __attribute((__section__(section))) \ 445 438 __no_kcsan __no_sanitize_address __no_profile __no_sanitize_coverage \ 446 - __no_sanitize_memory __signed_wrap 439 + __no_sanitize_memory 447 440 448 441 #define noinstr __noinstr_section(".noinstr.text") 449 442
+20 -34
include/linux/randomize_kstack.h
··· 6 6 #include <linux/kernel.h> 7 7 #include <linux/jump_label.h> 8 8 #include <linux/percpu-defs.h> 9 + #include <linux/prandom.h> 9 10 10 11 DECLARE_STATIC_KEY_MAYBE(CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT, 11 12 randomize_kstack_offset); 12 - DECLARE_PER_CPU(u32, kstack_offset); 13 13 14 14 /* 15 15 * Do not use this anywhere else in the kernel. This is used here because ··· 46 46 #define KSTACK_OFFSET_MAX(x) ((x) & 0b1111111100) 47 47 #endif 48 48 49 + DECLARE_PER_CPU(struct rnd_state, kstack_rnd_state); 50 + 51 + static __always_inline u32 get_kstack_offset(void) 52 + { 53 + struct rnd_state *state; 54 + u32 rnd; 55 + 56 + state = &get_cpu_var(kstack_rnd_state); 57 + rnd = prandom_u32_state(state); 58 + put_cpu_var(kstack_rnd_state); 59 + 60 + return rnd; 61 + } 62 + 49 63 /** 50 - * add_random_kstack_offset - Increase stack utilization by previously 51 - * chosen random offset 64 + * add_random_kstack_offset - Increase stack utilization by a random offset. 52 65 * 53 - * This should be used in the syscall entry path when interrupts and 54 - * preempt are disabled, and after user registers have been stored to 55 - * the stack. For testing the resulting entropy, please see: 56 - * tools/testing/selftests/lkdtm/stack-entropy.sh 66 + * This should be used in the syscall entry path after user registers have been 67 + * stored to the stack. Preemption may be enabled. For testing the resulting 68 + * entropy, please see: tools/testing/selftests/lkdtm/stack-entropy.sh 57 69 */ 58 70 #define add_random_kstack_offset() do { \ 59 71 if (static_branch_maybe(CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT, \ 60 72 &randomize_kstack_offset)) { \ 61 - u32 offset = raw_cpu_read(kstack_offset); \ 73 + u32 offset = get_kstack_offset(); \ 62 74 u8 *ptr = __kstack_alloca(KSTACK_OFFSET_MAX(offset)); \ 63 75 /* Keep allocation even after "ptr" loses scope. */ \ 64 76 asm volatile("" :: "r"(ptr) : "memory"); \ 65 77 } \ 66 78 } while (0) 67 79 68 - /** 69 - * choose_random_kstack_offset - Choose the random offset for the next 70 - * add_random_kstack_offset() 71 - * 72 - * This should only be used during syscall exit when interrupts and 73 - * preempt are disabled. This position in the syscall flow is done to 74 - * frustrate attacks from userspace attempting to learn the next offset: 75 - * - Maximize the timing uncertainty visible from userspace: if the 76 - * offset is chosen at syscall entry, userspace has much more control 77 - * over the timing between choosing offsets. "How long will we be in 78 - * kernel mode?" tends to be more difficult to predict than "how long 79 - * will we be in user mode?" 80 - * - Reduce the lifetime of the new offset sitting in memory during 81 - * kernel mode execution. Exposure of "thread-local" memory content 82 - * (e.g. current, percpu, etc) tends to be easier than arbitrary 83 - * location memory exposure. 84 - */ 85 - #define choose_random_kstack_offset(rand) do { \ 86 - if (static_branch_maybe(CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT, \ 87 - &randomize_kstack_offset)) { \ 88 - u32 offset = raw_cpu_read(kstack_offset); \ 89 - offset = ror32(offset, 5) ^ (rand); \ 90 - raw_cpu_write(kstack_offset, offset); \ 91 - } \ 92 - } while (0) 93 80 #else /* CONFIG_RANDOMIZE_KSTACK_OFFSET */ 94 81 #define add_random_kstack_offset() do { } while (0) 95 - #define choose_random_kstack_offset(rand) do { } while (0) 96 82 #endif /* CONFIG_RANDOMIZE_KSTACK_OFFSET */ 97 83 98 84 #endif
+5 -5
include/linux/refcount.h
··· 170 170 return atomic_read(&r->refs); 171 171 } 172 172 173 - static inline __must_check __signed_wrap 173 + static inline __must_check 174 174 bool __refcount_add_not_zero(int i, refcount_t *r, int *oldp) 175 175 { 176 176 int old = refcount_read(r); ··· 212 212 return __refcount_add_not_zero(i, r, NULL); 213 213 } 214 214 215 - static inline __must_check __signed_wrap 215 + static inline __must_check 216 216 bool __refcount_add_not_zero_limited_acquire(int i, refcount_t *r, int *oldp, 217 217 int limit) 218 218 { ··· 244 244 return __refcount_add_not_zero_limited_acquire(1, r, oldp, limit); 245 245 } 246 246 247 - static inline __must_check __signed_wrap 247 + static inline __must_check 248 248 bool __refcount_add_not_zero_acquire(int i, refcount_t *r, int *oldp) 249 249 { 250 250 return __refcount_add_not_zero_limited_acquire(i, r, oldp, INT_MAX); ··· 277 277 return __refcount_add_not_zero_acquire(i, r, NULL); 278 278 } 279 279 280 - static inline __signed_wrap 280 + static inline 281 281 void __refcount_add(int i, refcount_t *r, int *oldp) 282 282 { 283 283 int old = atomic_fetch_add_relaxed(i, &r->refs); ··· 383 383 __refcount_inc(r, NULL); 384 384 } 385 385 386 - static inline __must_check __signed_wrap 386 + static inline __must_check 387 387 bool __refcount_sub_and_test(int i, refcount_t *r, int *oldp) 388 388 { 389 389 int old = atomic_fetch_sub_release(i, &r->refs);
+8 -1
init/main.c
··· 833 833 #ifdef CONFIG_RANDOMIZE_KSTACK_OFFSET 834 834 DEFINE_STATIC_KEY_MAYBE_RO(CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT, 835 835 randomize_kstack_offset); 836 - DEFINE_PER_CPU(u32, kstack_offset); 836 + DEFINE_PER_CPU(struct rnd_state, kstack_rnd_state); 837 + 838 + static int __init random_kstack_init(void) 839 + { 840 + prandom_seed_full_state(&kstack_rnd_state); 841 + return 0; 842 + } 843 + late_initcall(random_kstack_init); 837 844 838 845 static int __init early_randomize_kstack_offset(char *buf) 839 846 {
+1
kernel/fork.c
··· 96 96 #include <linux/thread_info.h> 97 97 #include <linux/kstack_erase.h> 98 98 #include <linux/kasan.h> 99 + #include <linux/randomize_kstack.h> 99 100 #include <linux/scs.h> 100 101 #include <linux/io_uring.h> 101 102 #include <linux/io_uring_types.h>
-1
tools/testing/selftests/lkdtm/tests.txt
··· 82 82 CFI_FORWARD_PROTO 83 83 CFI_BACKWARD call trace:|ok: control flow unchanged 84 84 FORTIFY_STRSCPY detected buffer overflow 85 - FORTIFY_STR_OBJECT detected buffer overflow 86 85 FORTIFY_STR_MEMBER detected buffer overflow 87 86 FORTIFY_MEM_OBJECT detected buffer overflow 88 87 FORTIFY_MEM_MEMBER detected field-spanning write