From 51faada71a219a8b94cd8d8e423f0f22e9da4d8f Mon Sep 17 00:00:00 2001 From: Douglas Raillard Date: Fri, 24 Feb 2017 18:14:15 +0000 Subject: Add support for GCC stack protection Introduce new build option ENABLE_STACK_PROTECTOR. It enables compilation of all BL images with one of the GCC -fstack-protector-* options. A new platform function plat_get_stack_protector_canary() is introduced. It returns a value that is used to initialize the canary for stack corruption detection. Returning a random value will prevent an attacker from predicting the value and greatly increase the effectiveness of the protection. A message is printed at the ERROR level when a stack corruption is detected. To be effective, the global data must be stored at an address lower than the base of the stacks. Failure to do so would allow an attacker to overwrite the canary as part of an attack which would void the protection. FVP implementation of plat_get_stack_protector_canary is weak as there is no real source of entropy on the FVP. It therefore relies on a timer's value, which could be predictable. Change-Id: Icaaee96392733b721fa7c86a81d03660d3c1bc06 Signed-off-by: Douglas Raillard --- include/common/aarch32/el3_common_macros.S | 8 +++++++- include/common/aarch64/el3_common_macros.S | 6 ++++++ include/common/debug.h | 5 ++++- include/plat/common/platform.h | 14 +++++++++++++- 4 files changed, 30 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/common/aarch32/el3_common_macros.S b/include/common/aarch32/el3_common_macros.S index f6b7527e..d7e0b3f5 100644 --- a/include/common/aarch32/el3_common_macros.S +++ b/include/common/aarch32/el3_common_macros.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -278,6 +278,12 @@ * --------------------------------------------------------------------- */ bl plat_set_my_stack + +#if STACK_PROTECTOR_ENABLED + .if \_init_c_runtime + bl update_stack_protector_canary + .endif /* _init_c_runtime */ +#endif .endm #endif /* __EL3_COMMON_MACROS_S__ */ diff --git a/include/common/aarch64/el3_common_macros.S b/include/common/aarch64/el3_common_macros.S index e085f9f1..5c6aa069 100644 --- a/include/common/aarch64/el3_common_macros.S +++ b/include/common/aarch64/el3_common_macros.S @@ -283,6 +283,12 @@ * --------------------------------------------------------------------- */ bl plat_set_my_stack + +#if STACK_PROTECTOR_ENABLED + .if \_init_c_runtime + bl update_stack_protector_canary + .endif /* _init_c_runtime */ +#endif .endm #endif /* __EL3_COMMON_MACROS_S__ */ diff --git a/include/common/debug.h b/include/common/debug.h index 41c8df0c..c6f211f3 100644 --- a/include/common/debug.h +++ b/include/common/debug.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -84,6 +84,9 @@ void __dead2 do_panic(void); #define panic() do_panic() +/* Function called when stack protection check code detects a corrupted stack */ +void __dead2 __stack_chk_fail(void); + void tf_printf(const char *fmt, ...) __printflike(1, 2); #endif /* __ASSEMBLY__ */ diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index 73bb6431..f13b30d8 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -72,6 +72,16 @@ uintptr_t plat_get_ns_image_entrypoint(void); unsigned int plat_my_core_pos(void); int plat_core_pos_by_mpidr(u_register_t mpidr); +#if STACK_PROTECTOR_ENABLED +/* + * Return a new value to be used for the stack protection's canary. + * + * Ideally, this value is a random number that is impossible to predict by an + * attacker. + */ +u_register_t plat_get_stack_protector_canary(void); +#endif /* STACK_PROTECTOR_ENABLED */ + /******************************************************************************* * Mandatory interrupt management functions ******************************************************************************/ @@ -326,7 +336,7 @@ int platform_setup_pm(const plat_pm_ops_t **); unsigned int plat_get_aff_count(unsigned int, unsigned long); unsigned int plat_get_aff_state(unsigned int, unsigned long); -#else +#else /* __ENABLE_PLAT_COMPAT__ */ /* * The below function enable Trusted Firmware components like SPDs which * haven't migrated to the new platform API to compile on platforms which @@ -335,4 +345,6 @@ unsigned int plat_get_aff_state(unsigned int, unsigned long); unsigned int platform_get_core_pos(unsigned long mpidr) __deprecated; #endif /* __ENABLE_PLAT_COMPAT__ */ + #endif /* __PLATFORM_H__ */ + -- cgit v1.2.3 From 233d83d06c22adaefc82dcacbe8b29ab20d76c35 Mon Sep 17 00:00:00 2001 From: dp-arm Date: Tue, 21 Mar 2017 15:38:06 +0000 Subject: Introduce MIN()/MAX() macros in utils.h Change-Id: If88270bc9edb32634a793b1e1be6c4829f39b9c5 Signed-off-by: dp-arm --- include/lib/utils.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'include') diff --git a/include/lib/utils.h b/include/lib/utils.h index 69bbb430..279c9135 100644 --- a/include/lib/utils.h +++ b/include/lib/utils.h @@ -42,6 +42,20 @@ #define BIT(nr) (1UL << (nr)) +#define MIN(x, y) __extension__ ({ \ + __typeof__(x) _x = (x); \ + __typeof__(y) _y = (y); \ + (void)(&_x == &_y); \ + _x < _y ? _x : _y; \ +}) + +#define MAX(x, y) __extension__ ({ \ + __typeof__(x) _x = (x); \ + __typeof__(y) _y = (y); \ + (void)(&_x == &_y); \ + _x > _y ? _x : _y; \ +}) + /* * The round_up() macro rounds up a value to the given boundary in a * type-agnostic yet type-safe manner. The boundary must be a power of two. -- cgit v1.2.3