From d81505336030a1d9f2704c2d87e4f6c333f72963 Mon Sep 17 00:00:00 2001 From: Aidan MacDonald Date: Tue, 21 Apr 2026 14:33:58 +0100 Subject: [PATCH] Add support for -fstack-protector in native builds -fstack-protector only needs a small amount of runtime support to work on native builds. It increases code size by ~1.5% on ARM/MIPS; -fstack-protector-strong adds 3-4%. This is disabled by default and must be enabled by passing '--with-stack-protector' to configure. Change-Id: If952e711d3673c9b469895f08c7bff70b3d95df6 --- apps/plugins/lib/gcc-support.c | 9 +++++++++ firmware/asm/SOURCES | 4 ++++ firmware/asm/stack-protector.c | 29 +++++++++++++++++++++++++++++ lib/rbcodec/codecs/codec_crt0.c | 9 +++++++++ tools/configure | 17 +++++++++++++++++ 5 files changed, 68 insertions(+) create mode 100644 firmware/asm/stack-protector.c diff --git a/apps/plugins/lib/gcc-support.c b/apps/plugins/lib/gcc-support.c index f1fbe4ec58..53b01b9f01 100644 --- a/apps/plugins/lib/gcc-support.c +++ b/apps/plugins/lib/gcc-support.c @@ -34,6 +34,15 @@ void __aeabi_ldiv0(void) __attribute__((alias("__div0"))); #endif #endif +#if defined(USE_STACK_PROTECTOR) +const uint32_t __stack_chk_guard = 0x3BADC0DE; + +void __stack_chk_fail(void) +{ + rb->panicf("plugin smashed stack"); +} +#endif + void *memcpy(void *dest, const void *src, size_t n) { return rb->memcpy(dest, src, n); diff --git a/firmware/asm/SOURCES b/firmware/asm/SOURCES index 463c120213..74ba94c204 100644 --- a/firmware/asm/SOURCES +++ b/firmware/asm/SOURCES @@ -65,3 +65,7 @@ lcd-as-memframe.c #endif /* CPU_ARM */ #endif /* LCD_DEPTH */ #endif + +#if defined(USE_STACK_PROTECTOR) +stack-protector.c +#endif diff --git a/firmware/asm/stack-protector.c b/firmware/asm/stack-protector.c new file mode 100644 index 0000000000..b0de405980 --- /dev/null +++ b/firmware/asm/stack-protector.c @@ -0,0 +1,29 @@ +/*************************************************************************** +* __________ __ ___. +* Open \______ \ ____ ____ | | _\_ |__ _______ ___ +* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +* \/ \/ \/ \/ \/ +* $Id$ +* +* Copyright (C) 2026 by Aidan MacDonald +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +* KIND, either express or implied +* +****************************************************************************/ +#include "panic.h" +#include + +const uint32_t __stack_chk_guard = 0x1BADC0DE; + +void __stack_chk_fail(void) +{ + panicf("stack smashing detected"); +} diff --git a/lib/rbcodec/codecs/codec_crt0.c b/lib/rbcodec/codecs/codec_crt0.c index e95b3e31e6..54035fc232 100644 --- a/lib/rbcodec/codecs/codec_crt0.c +++ b/lib/rbcodec/codecs/codec_crt0.c @@ -78,3 +78,12 @@ void __attribute__((naked)) __div0(void) asm volatile("bx %0" : : "r"(ci->__div0)); } #endif + +#if defined(USE_STACK_PROTECTOR) +const uint32_t __stack_chk_guard = 0x2BADC0DE; + +void __stack_chk_fail(void) +{ + ci->panicf("codec smashed stack"); +} +#endif diff --git a/tools/configure b/tools/configure index 4e6439a0c1..27fb62803c 100755 --- a/tools/configure +++ b/tools/configure @@ -1531,6 +1531,9 @@ help() { --with-address-sanitizer Enables the AddressSanitizer feature. Forces SDL threads. --with-ubsan Enables the UB Sanitizer feature. Forces SDL threads. + --with-stack-protector[=MODE] + Enable -fstack-protector-MODE option. With no MODE, + enables the normal -fstack-protector option. --32-bit Force a 32-bit simulator (use with --sdl-threads for duke3d) --prefix Target installation directory --compiler-prefix Override compiler prefix (inherently dangerous) @@ -1557,6 +1560,7 @@ ARG_THREAD_SUPPORT= ARG_32BIT= ARG_ADDR_SAN= ARG_UBSAN= +ARG_STACK_PROTECTOR= ARG_PLUGINS= err= for arg in "$@"; do @@ -1583,6 +1587,8 @@ for arg in "$@"; do ARG_THREAD_SUPPORT=0;; --with-address-sanitizer) ARG_ADDR_SAN=1;; --with-ubsan) ARG_UBSAN=1;; + --with-stack-protector=*) ARG_STACK_PROTECTOR=`echo "$arg" | cut -d = -f 2`;; + --with-stack-protector) ARG_STACK_PROTECTOR=default;; --prefix=*) ARG_PREFIX=`echo "$arg" | cut -d = -f 2`;; --compiler-prefix=*) ARG_COMPILER_PREFIX=`echo "$arg" | cut -d = -f 2`;; --help) help;; @@ -4694,6 +4700,17 @@ if [ "$ARG_RBDIR" != "" ]; then echo "Using alternate rockbox dir: ${rbdir}" fi +if [ "$ARG_STACK_PROTECTOR" != "" ]; then + echo "Stack protector mode: $ARG_STACK_PROTECTOR" + extradefines="$extradefines -DUSE_STACK_PROTECTOR" + + if [ "$ARG_STACK_PROTECTOR" = "default" ]; then + GCCOPTS="$GCCOPTS -fstack-protector" + else + GCCOPTS="$GCCOPTS -fstack-protector-${ARG_STACK_PROTECTOR}" + fi +fi + cat > autoconf.h.new <