[PATCH v3 2/2] firmware: Initial compiler built-in stack protector support

Peter Lin peter.lin at sifive.com
Fri Jul 4 03:58:17 PDT 2025


On Thu, Jul 3, 2025 at 11:20 PM Alvin Chang <alvinga at andestech.com> wrote:
>
> 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 at andestech.com>

Reviewed-by: Yu-Chien Peter Lin <peter.lin at sifive.com>

> ---
>  firmware/Kconfig              | 27 +++++++++++++++++++++++++++
>  firmware/fw_base.S            | 21 +++++++++++++++++++++
>  firmware/objects.mk           |  9 +++++++++
>  firmware/payloads/test_head.S | 15 +++++++++++++++
>  4 files changed, 72 insertions(+)
>
> 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
> --
> 2.43.0
>



More information about the opensbi mailing list