[PATCH v2 2/2] firmware: Initial compiler built-in stack protector support
Peter Lin
peter.lin at sifive.com
Thu Jun 26 02:08:00 PDT 2025
Hi Alvin, Xiang,
On Wed, Jun 25, 2025 at 1:32 PM Xiang W <wxjstz at 126.com> wrote:
>
> 在 2025-06-25三的 11:16 +0800,Alvin Chang写道:
> > 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>
> > ---
> > firmware/Kconfig | 27 +++++++++++++++++++++++++++
> > firmware/fw_base.S | 17 +++++++++++++++++
> > firmware/objects.mk | 9 +++++++++
> > firmware/payloads/test_head.S | 17 +++++++++++++++++
> > 4 files changed, 70 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..9dc73d0 100644
> > --- a/firmware/fw_base.S
> > +++ b/firmware/fw_base.S
> > @@ -736,6 +736,23 @@ _reset_regs:
> >
> > ret
> >
> > + /* This will be called when the stack corruption is detected */
> > + .section .text
> > + .align 3
> > + .globl __stack_chk_fail
> > + .type __stack_chk_fail, %function
>
> The function can be removed to create an alias, as shown below:
>
> > +__stack_chk_fail:
> > + wfi
> > + j __stack_chk_fail
>
> .equ __stack_chk_fail, _start_hang
How about adding an error message as PATCHv1.
+ .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:
- wfi
- j __stack_chk_fail
+ la a0, .Lstack_corrupt_msg
+ call sbi_panic
Otherwise it looks no different when the stack protector is disabled.
Regards,
Peter Lin
> Regards,
> Xiang W
> > +
> > + /* 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..b5fd46b 100644
> > --- a/firmware/payloads/test_head.S
> > +++ b/firmware/payloads/test_head.S
> > @@ -97,3 +97,20 @@ _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
> > +__stack_chk_fail:
> > + wfi
> > + j __stack_chk_fail
> > +
> > + /* 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