Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * This code fills the used part of the kernel stack with a poison value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * before returning to userspace. It's part of the STACKLEAK feature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * ported from grsecurity/PaX.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Author: Alexander Popov <alex.popov@linux.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * STACKLEAK reduces the information which kernel stack leak bugs can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * reveal and blocks some uninitialized stack variable attacks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/stackleak.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/kprobes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #ifdef CONFIG_STACKLEAK_RUNTIME_DISABLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/jump_label.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/sysctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) static DEFINE_STATIC_KEY_FALSE(stack_erasing_bypass);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) int stack_erasing_sysctl(struct ctl_table *table, int write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 			void *buffer, size_t *lenp, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	int state = !static_branch_unlikely(&stack_erasing_bypass);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	int prev_state = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	table->data = &state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	table->maxlen = sizeof(int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	state = !!state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	if (ret || !write || state == prev_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	if (state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 		static_branch_disable(&stack_erasing_bypass);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 		static_branch_enable(&stack_erasing_bypass);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	pr_warn("stackleak: kernel stack erasing is %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 					state ? "enabled" : "disabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define skip_erasing()	static_branch_unlikely(&stack_erasing_bypass)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #define skip_erasing()	false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #endif /* CONFIG_STACKLEAK_RUNTIME_DISABLE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) asmlinkage void noinstr stackleak_erase(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	/* It would be nice not to have 'kstack_ptr' and 'boundary' on stack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	unsigned long kstack_ptr = current->lowest_stack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	unsigned long boundary = (unsigned long)end_of_stack(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	unsigned int poison_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	const unsigned int depth = STACKLEAK_SEARCH_DEPTH / sizeof(unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	if (skip_erasing())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	/* Check that 'lowest_stack' value is sane */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	if (unlikely(kstack_ptr - boundary >= THREAD_SIZE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		kstack_ptr = boundary;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	/* Search for the poison value in the kernel stack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	while (kstack_ptr > boundary && poison_count <= depth) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		if (*(unsigned long *)kstack_ptr == STACKLEAK_POISON)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 			poison_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 			poison_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		kstack_ptr -= sizeof(unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	 * One 'long int' at the bottom of the thread stack is reserved and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	 * should not be poisoned (see CONFIG_SCHED_STACK_END_CHECK=y).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	if (kstack_ptr == boundary)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		kstack_ptr += sizeof(unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) #ifdef CONFIG_STACKLEAK_METRICS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	current->prev_lowest_stack = kstack_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	 * Now write the poison value to the kernel stack. Start from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	 * 'kstack_ptr' and move up till the new 'boundary'. We assume that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	 * the stack pointer doesn't change when we write poison.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	if (on_thread_stack())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		boundary = current_stack_pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		boundary = current_top_of_stack();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	while (kstack_ptr < boundary) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		*(unsigned long *)kstack_ptr = STACKLEAK_POISON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		kstack_ptr += sizeof(unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	/* Reset the 'lowest_stack' value for the next syscall */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	current->lowest_stack = current_top_of_stack() - THREAD_SIZE/64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) void __used __no_caller_saved_registers noinstr stackleak_track_stack(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	unsigned long sp = current_stack_pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	 * Having CONFIG_STACKLEAK_TRACK_MIN_SIZE larger than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	 * STACKLEAK_SEARCH_DEPTH makes the poison search in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	 * stackleak_erase() unreliable. Let's prevent that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	BUILD_BUG_ON(CONFIG_STACKLEAK_TRACK_MIN_SIZE > STACKLEAK_SEARCH_DEPTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	/* 'lowest_stack' should be aligned on the register width boundary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	sp = ALIGN(sp, sizeof(unsigned long));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	if (sp < current->lowest_stack &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	    sp >= (unsigned long)task_stack_page(current) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 						sizeof(unsigned long)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		current->lowest_stack = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) EXPORT_SYMBOL(stackleak_track_stack);