Issue #20: Add stack checking based on protection area between stack and heap
This commit is contained in:
		@@ -347,6 +347,8 @@ void safety_controller_init()
 | 
				
			|||||||
	/* This is usually done by the safety memory already. But, since this module also uses the CRC... */
 | 
						/* This is usually done by the safety memory already. But, since this module also uses the CRC... */
 | 
				
			||||||
	crc_unit_init();
 | 
						crc_unit_init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						stack_check_init_corruption_detect_area();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	init_safety_flag_weight_table_from_default();
 | 
						init_safety_flag_weight_table_from_default();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (found_memory_state == SAFETY_MEMORY_INIT_CORRUPTED)
 | 
						if (found_memory_state == SAFETY_MEMORY_INIT_CORRUPTED)
 | 
				
			||||||
@@ -374,6 +376,10 @@ static void safety_controller_check_stack()
 | 
				
			|||||||
	free_stack = stack_check_get_free();
 | 
						free_stack = stack_check_get_free();
 | 
				
			||||||
	if (free_stack < SAFETY_MIN_STACK_FREE)
 | 
						if (free_stack < SAFETY_MIN_STACK_FREE)
 | 
				
			||||||
		safety_controller_report_error(ERR_FLAG_STACK);
 | 
							safety_controller_report_error(ERR_FLAG_STACK);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (stack_check_corruption_detect_area()) {
 | 
				
			||||||
 | 
							safety_controller_report_error(ERR_FLAG_STACK);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void safety_controller_handle_safety_adc()
 | 
					static void safety_controller_handle_safety_adc()
 | 
				
			||||||
@@ -430,7 +436,7 @@ static int safety_controller_handle_memory_checks(void)
 | 
				
			|||||||
	enum safety_memory_state found_state;
 | 
						enum safety_memory_state found_state;
 | 
				
			||||||
	int panic_request = 0;
 | 
						int panic_request = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (systick_ticks_have_passed(ts, 1000)) {
 | 
						if (systick_ticks_have_passed(ts, 250)) {
 | 
				
			||||||
		ts = systick_get_global_tick();
 | 
							ts = systick_get_global_tick();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Check the safety memory */
 | 
							/* Check the safety memory */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,6 +21,7 @@
 | 
				
			|||||||
#include <reflow-controller/stack-check.h>
 | 
					#include <reflow-controller/stack-check.h>
 | 
				
			||||||
#include <stdint.h>
 | 
					#include <stdint.h>
 | 
				
			||||||
#include <stm-periph/rng.h>
 | 
					#include <stm-periph/rng.h>
 | 
				
			||||||
 | 
					#include <stm-periph/crc-unit.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern char __ld_top_of_stack;
 | 
					extern char __ld_top_of_stack;
 | 
				
			||||||
extern char __ld_end_stack;
 | 
					extern char __ld_end_stack;
 | 
				
			||||||
@@ -47,22 +48,27 @@ int32_t stack_check_get_free()
 | 
				
			|||||||
	return stack_ptr - upper_heap_boundary;
 | 
						return stack_ptr - upper_heap_boundary;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma GCC diagnostic push
 | 
				
			||||||
 | 
					#pragma GCC diagnostic ignored "-Warray-bounds"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern uint32_t __ld_start_stack_corruption_detect_area;
 | 
					extern uint32_t __ld_start_stack_corruption_detect_area;
 | 
				
			||||||
extern uint32_t __ld_end_stack_corruption_detect_area;
 | 
					extern uint32_t __ld_end_stack_corruption_detect_area;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int stack_check_init_corruption_detect_area(void)
 | 
					int stack_check_init_corruption_detect_area(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	volatile uint32_t *ptr = &__ld_start_stack_corruption_detect_area;
 | 
						uint32_t *ptr = &__ld_start_stack_corruption_detect_area;
 | 
				
			||||||
	volatile uint32_t *end_ptr = &__ld_end_stack_corruption_detect_area;
 | 
						uint32_t *end_ptr = &__ld_end_stack_corruption_detect_area;
 | 
				
			||||||
 | 
						const uint32_t area_size_in_words = &__ld_end_stack_corruption_detect_area -
 | 
				
			||||||
 | 
											&__ld_start_stack_corruption_detect_area;
 | 
				
			||||||
	enum random_number_error rng_stat;
 | 
						enum random_number_error rng_stat;
 | 
				
			||||||
	uint32_t rng_number;
 | 
						uint32_t rng_number;
 | 
				
			||||||
 | 
						uint32_t crc_val;
 | 
				
			||||||
	int ret = 0;
 | 
						int ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	end_ptr--;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	random_number_gen_init(false);
 | 
						random_number_gen_init(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while (ptr < end_ptr) {
 | 
						while (ptr < &end_ptr[-1]) {
 | 
				
			||||||
		rng_stat = random_number_gen_get_number(&rng_number, true);
 | 
							rng_stat = random_number_gen_get_number(&rng_number, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (rng_stat != RNG_ERROR_OK) {
 | 
							if (rng_stat != RNG_ERROR_OK) {
 | 
				
			||||||
@@ -74,13 +80,31 @@ int stack_check_init_corruption_detect_area(void)
 | 
				
			|||||||
		ptr++;
 | 
							ptr++;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Init CRC unit and leave it on */
 | 
				
			||||||
 | 
						crc_unit_init();
 | 
				
			||||||
 | 
						crc_unit_reset();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						crc_unit_input_array(&__ld_start_stack_corruption_detect_area, area_size_in_words - 1);
 | 
				
			||||||
 | 
						crc_val = crc_unit_get_crc();
 | 
				
			||||||
 | 
						end_ptr[-1] = crc_val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
exit_deinit_rng:
 | 
					exit_deinit_rng:
 | 
				
			||||||
	random_number_gen_deinit();
 | 
						random_number_gen_deinit();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma GCC diagnostic pop
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int stack_check_corruption_detect_area(void)
 | 
					int stack_check_corruption_detect_area(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						const uint32_t area_size_in_words = &__ld_end_stack_corruption_detect_area -
 | 
				
			||||||
 | 
											&__ld_start_stack_corruption_detect_area;
 | 
				
			||||||
 | 
						crc_unit_reset();
 | 
				
			||||||
 | 
						crc_unit_input_array(&__ld_start_stack_corruption_detect_area, area_size_in_words);
 | 
				
			||||||
 | 
						if (crc_unit_get_crc() == 0UL) {
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,7 +25,7 @@
 | 
				
			|||||||
/* USER PARAMETERS */
 | 
					/* USER PARAMETERS */
 | 
				
			||||||
__ld_stack_size = 0x3000;
 | 
					__ld_stack_size = 0x3000;
 | 
				
			||||||
__ld_heap_size  = 0x2100;
 | 
					__ld_heap_size  = 0x2100;
 | 
				
			||||||
__stack_corruption_area_size = 64;
 | 
					__stack_corruption_area_size = 128;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* END OF USER PARAMETERS */
 | 
					/* END OF USER PARAMETERS */
 | 
				
			||||||
ENTRY(Reset_Handler)
 | 
					ENTRY(Reset_Handler)
 | 
				
			||||||
@@ -151,12 +151,12 @@ SECTIONS
 | 
				
			|||||||
		__ld_sheap = .;
 | 
							__ld_sheap = .;
 | 
				
			||||||
		. = . + __ld_heap_size;
 | 
							. = . + __ld_heap_size;
 | 
				
			||||||
		__ld_eheap = .;
 | 
							__ld_eheap = .;
 | 
				
			||||||
		. = ALIGN(4)
 | 
							. = ALIGN(4);
 | 
				
			||||||
		__ld_start_stack_corruption_detect_area = .;
 | 
							__ld_start_stack_corruption_detect_area = .;
 | 
				
			||||||
		. = . + __stack_corruption_area_size;
 | 
							. = . + __stack_corruption_area_size;
 | 
				
			||||||
		. = ALIGN(4);
 | 
							. = ALIGN(4);
 | 
				
			||||||
		__ld_end_stack_corruption_detect_area = .;
 | 
							__ld_end_stack_corruption_detect_area = .;
 | 
				
			||||||
		__ld_end_stack = .
 | 
							__ld_end_stack = .;
 | 
				
			||||||
		. = . + __ld_stack_size;
 | 
							. = . + __ld_stack_size;
 | 
				
			||||||
		. = ALIGN(4);
 | 
							. = ALIGN(4);
 | 
				
			||||||
	} >RAM
 | 
						} >RAM
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user