| 1 | /* SPDX-License-Identifier: GPL-2.0-only */ | 
|---|
| 2 | #ifndef _LINUX_RANDOMIZE_KSTACK_H | 
|---|
| 3 | #define _LINUX_RANDOMIZE_KSTACK_H | 
|---|
| 4 |  | 
|---|
| 5 | #ifdef CONFIG_RANDOMIZE_KSTACK_OFFSET | 
|---|
| 6 | #include <linux/kernel.h> | 
|---|
| 7 | #include <linux/jump_label.h> | 
|---|
| 8 | #include <linux/percpu-defs.h> | 
|---|
| 9 |  | 
|---|
| 10 | DECLARE_STATIC_KEY_MAYBE(CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT, | 
|---|
| 11 | randomize_kstack_offset); | 
|---|
| 12 | DECLARE_PER_CPU(u32, kstack_offset); | 
|---|
| 13 |  | 
|---|
| 14 | /* | 
|---|
| 15 | * Do not use this anywhere else in the kernel. This is used here because | 
|---|
| 16 | * it provides an arch-agnostic way to grow the stack with correct | 
|---|
| 17 | * alignment. Also, since this use is being explicitly masked to a max of | 
|---|
| 18 | * 10 bits, stack-clash style attacks are unlikely. For more details see | 
|---|
| 19 | * "VLAs" in Documentation/process/deprecated.rst | 
|---|
| 20 | * | 
|---|
| 21 | * The normal __builtin_alloca() is initialized with INIT_STACK_ALL (currently | 
|---|
| 22 | * only with Clang and not GCC). Initializing the unused area on each syscall | 
|---|
| 23 | * entry is expensive, and generating an implicit call to memset() may also be | 
|---|
| 24 | * problematic (such as in noinstr functions). Therefore, if the compiler | 
|---|
| 25 | * supports it (which it should if it initializes allocas), always use the | 
|---|
| 26 | * "uninitialized" variant of the builtin. | 
|---|
| 27 | */ | 
|---|
| 28 | #if __has_builtin(__builtin_alloca_uninitialized) | 
|---|
| 29 | #define __kstack_alloca __builtin_alloca_uninitialized | 
|---|
| 30 | #else | 
|---|
| 31 | #define __kstack_alloca __builtin_alloca | 
|---|
| 32 | #endif | 
|---|
| 33 |  | 
|---|
| 34 | /* | 
|---|
| 35 | * Use, at most, 6 bits of entropy (on 64-bit; 8 on 32-bit). This cap is | 
|---|
| 36 | * to keep the "VLA" from being unbounded (see above). Additionally clear | 
|---|
| 37 | * the bottom 4 bits (on 64-bit systems, 2 for 32-bit), since stack | 
|---|
| 38 | * alignment will always be at least word size. This makes the compiler | 
|---|
| 39 | * code gen better when it is applying the actual per-arch alignment to | 
|---|
| 40 | * the final offset. The resulting randomness is reasonable without overly | 
|---|
| 41 | * constraining usable stack space. | 
|---|
| 42 | */ | 
|---|
| 43 | #ifdef CONFIG_64BIT | 
|---|
| 44 | #define KSTACK_OFFSET_MAX(x)	((x) & 0b1111110000) | 
|---|
| 45 | #else | 
|---|
| 46 | #define KSTACK_OFFSET_MAX(x)	((x) & 0b1111111100) | 
|---|
| 47 | #endif | 
|---|
| 48 |  | 
|---|
| 49 | /** | 
|---|
| 50 | * add_random_kstack_offset - Increase stack utilization by previously | 
|---|
| 51 | *			      chosen random offset | 
|---|
| 52 | * | 
|---|
| 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 | 
|---|
| 57 | */ | 
|---|
| 58 | #define add_random_kstack_offset() do {					\ | 
|---|
| 59 | if (static_branch_maybe(CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT,	\ | 
|---|
| 60 | &randomize_kstack_offset)) {		\ | 
|---|
| 61 | u32 offset = raw_cpu_read(kstack_offset);		\ | 
|---|
| 62 | u8 *ptr = __kstack_alloca(KSTACK_OFFSET_MAX(offset));	\ | 
|---|
| 63 | /* Keep allocation even after "ptr" loses scope. */	\ | 
|---|
| 64 | asm volatile("" :: "r"(ptr) : "memory");		\ | 
|---|
| 65 | }								\ | 
|---|
| 66 | } while (0) | 
|---|
| 67 |  | 
|---|
| 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 | #else /* CONFIG_RANDOMIZE_KSTACK_OFFSET */ | 
|---|
| 94 | #define add_random_kstack_offset()		do { } while (0) | 
|---|
| 95 | #define choose_random_kstack_offset(rand)	do { } while (0) | 
|---|
| 96 | #endif /* CONFIG_RANDOMIZE_KSTACK_OFFSET */ | 
|---|
| 97 |  | 
|---|
| 98 | #endif | 
|---|
| 99 |  | 
|---|