aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlvin Chang <alvinga@andestech.com>2025-07-03 23:19:57 +0800
committerAnup Patel <anup@brainfault.org>2025-07-20 20:54:34 +0530
commitedfbc1285dd9ac624665fe9fa5de26437d61c1eb (patch)
tree42840145378dd5c8a2d5195401e9a42f6eeb2dc4
parentea5abd1f5e33ed3afedc92686ec8bfd00bc49235 (diff)
downloadopensbi-edfbc1285dd9ac624665fe9fa5de26437d61c1eb.zip
opensbi-edfbc1285dd9ac624665fe9fa5de26437d61c1eb.tar.gz
opensbi-edfbc1285dd9ac624665fe9fa5de26437d61c1eb.tar.bz2
firmware: Initial compiler built-in stack protector support
Add __stack_chk_fail() and __stack_chk_guard variable which are used by compiler built-in stack protector. This patch just try to support stack-protector so the value of the stack guard variable is simply fixed for now. It could be improved by deriving from a random number generator, such as Zkr extension or any platform-specific random number sources. Introduce three configurations for the stack protector: 1. CONFIG_STACK_PROTECTOR to enable the stack protector feature by providing "-fstack-protector" compiler flag 2. CONFIG_STACK_PROTECTOR_STRONG to provide "-fstack-protector-strong" 3. CONFIG_STACK_PROTECTOR_ALL to provide "-fstack-protector-all" Instead of fixing the compiler flag of stack-protector feature as "-fstack-protector", we derive it from the introduced Kconfig configurations. The compiler flag "stack-protector-cflags-y" is defined as Makefile "immediately expanded variables" with ":=". Thus, the stronger configuration of the stack protector can overwrite the preceding one. Signed-off-by: Alvin Chang <alvinga@andestech.com> Reviewed-by: Yu-Chien Peter Lin <peter.lin@sifive.com> Reviewed-by: Anup Patel <anup@brainfault.org> Link: https://lore.kernel.org/r/20250703151957.2545958-3-alvinga@andestech.com Signed-off-by: Anup Patel <anup@brainfault.org>
-rw-r--r--firmware/Kconfig27
-rw-r--r--firmware/fw_base.S21
-rw-r--r--firmware/objects.mk9
-rw-r--r--firmware/payloads/test_head.S15
4 files changed, 72 insertions, 0 deletions
diff --git a/firmware/Kconfig b/firmware/Kconfig
index d6e0506..c1fee19 100644
--- a/firmware/Kconfig
+++ b/firmware/Kconfig
@@ -1 +1,28 @@
# SPDX-License-Identifier: BSD-2-Clause
+
+menu "Stack Protector Support"
+
+config STACK_PROTECTOR
+ bool "Stack Protector buffer overflow detection"
+ default n
+ help
+ This option turns on the "stack-protector" compiler feature.
+
+config STACK_PROTECTOR_STRONG
+ bool "Strong Stack Protector"
+ depends on STACK_PROTECTOR
+ default n
+ help
+ Turn on the "stack-protector" with "-fstack-protector-strong" option.
+ Like -fstack-protector but includes additional functions to be
+ protected.
+
+config STACK_PROTECTOR_ALL
+ bool "Almighty Stack Protector"
+ depends on STACK_PROTECTOR
+ default n
+ help
+ Turn on the "stack-protector" with "-fstack-protector-all" option.
+ Like -fstack-protector except that all functions are protected.
+
+endmenu
diff --git a/firmware/fw_base.S b/firmware/fw_base.S
index 2498797..a008fa7 100644
--- a/firmware/fw_base.S
+++ b/firmware/fw_base.S
@@ -736,6 +736,27 @@ _reset_regs:
ret
+ .section .rodata
+.Lstack_corrupt_msg:
+ .string "stack smashing detected\n"
+
+ /* This will be called when the stack corruption is detected */
+ .section .text
+ .align 3
+ .globl __stack_chk_fail
+ .type __stack_chk_fail, %function
+__stack_chk_fail:
+ la a0, .Lstack_corrupt_msg
+ call sbi_panic
+
+ /* Initial value of the stack guard variable */
+ .section .data
+ .align 3
+ .globl __stack_chk_guard
+ .type __stack_chk_guard, %object
+__stack_chk_guard:
+ RISCV_PTR 0x95B5FF5A
+
#ifdef FW_FDT_PATH
.section .rodata
.align 4
diff --git a/firmware/objects.mk b/firmware/objects.mk
index a90485d..bfec467 100644
--- a/firmware/objects.mk
+++ b/firmware/objects.mk
@@ -66,3 +66,12 @@ endif
ifdef FW_OPTIONS
firmware-genflags-y += -DFW_OPTIONS=$(FW_OPTIONS)
endif
+
+ifeq ($(CONFIG_STACK_PROTECTOR),y)
+stack-protector-cflags-$(CONFIG_STACK_PROTECTOR) := -fstack-protector
+stack-protector-cflags-$(CONFIG_STACK_PROTECTOR_STRONG) := -fstack-protector-strong
+stack-protector-cflags-$(CONFIG_STACK_PROTECTOR_ALL) := -fstack-protector-all
+else
+stack-protector-cflags-y := -fno-stack-protector
+endif
+firmware-cflags-y += $(stack-protector-cflags-y)
diff --git a/firmware/payloads/test_head.S b/firmware/payloads/test_head.S
index 7d25e07..070ce8a 100644
--- a/firmware/payloads/test_head.S
+++ b/firmware/payloads/test_head.S
@@ -97,3 +97,18 @@ _boot_a0:
RISCV_PTR 0
_boot_a1:
RISCV_PTR 0
+
+ /* This will be called when the stack corruption is detected */
+ .section .text
+ .align 3
+ .globl __stack_chk_fail
+ .type __stack_chk_fail, %function
+ .equ __stack_chk_fail, _start_hang
+
+ /* Initial value of the stack guard variable */
+ .section .data
+ .align 3
+ .globl __stack_chk_guard
+ .type __stack_chk_guard, %object
+__stack_chk_guard:
+ RISCV_PTR 0x95B5FF5A