17188d463SThomas Weißschuh /* SPDX-License-Identifier: LGPL-2.1 OR MIT */
27188d463SThomas Weißschuh /*
37188d463SThomas Weißschuh * Stack protector support for NOLIBC
47188d463SThomas Weißschuh * Copyright (C) 2023 Thomas Weißschuh <[email protected]>
57188d463SThomas Weißschuh */
67188d463SThomas Weißschuh
77188d463SThomas Weißschuh #ifndef _NOLIBC_STACKPROTECTOR_H
87188d463SThomas Weißschuh #define _NOLIBC_STACKPROTECTOR_H
97188d463SThomas Weißschuh
10818924d1SThomas Weißschuh #include "compiler.h"
117188d463SThomas Weißschuh
12818924d1SThomas Weißschuh #if defined(_NOLIBC_STACKPROTECTOR)
137188d463SThomas Weißschuh
147188d463SThomas Weißschuh #include "sys.h"
157188d463SThomas Weißschuh #include "stdlib.h"
167188d463SThomas Weißschuh
177188d463SThomas Weißschuh /* The functions in this header are using raw syscall macros to avoid
187188d463SThomas Weißschuh * triggering stack protector errors themselves
197188d463SThomas Weißschuh */
207188d463SThomas Weißschuh
21*0de64754SThomas Weißschuh void __stack_chk_fail(void);
22ff7b9abbSThomas Weißschuh __attribute__((weak,used,noreturn,section(".text.nolibc_stack_chk")))
__stack_chk_fail(void)237188d463SThomas Weißschuh void __stack_chk_fail(void)
247188d463SThomas Weißschuh {
257188d463SThomas Weißschuh pid_t pid;
267188d463SThomas Weißschuh my_syscall3(__NR_write, STDERR_FILENO, "!!Stack smashing detected!!\n", 28);
277188d463SThomas Weißschuh pid = my_syscall0(__NR_getpid);
287188d463SThomas Weißschuh my_syscall2(__NR_kill, pid, SIGABRT);
297188d463SThomas Weißschuh for (;;);
307188d463SThomas Weißschuh }
317188d463SThomas Weißschuh
32*0de64754SThomas Weißschuh void __stack_chk_fail_local(void);
337188d463SThomas Weißschuh __attribute__((weak,noreturn,section(".text.nolibc_stack_chk")))
__stack_chk_fail_local(void)347188d463SThomas Weißschuh void __stack_chk_fail_local(void)
357188d463SThomas Weißschuh {
367188d463SThomas Weißschuh __stack_chk_fail();
377188d463SThomas Weißschuh }
387188d463SThomas Weißschuh
39ff7b9abbSThomas Weißschuh __attribute__((weak,used,section(".data.nolibc_stack_chk")))
407188d463SThomas Weißschuh uintptr_t __stack_chk_guard;
417188d463SThomas Weißschuh
__stack_chk_init(void)42dcb677c3SZhangjin Wu static __no_stack_protector void __stack_chk_init(void)
437188d463SThomas Weißschuh {
447188d463SThomas Weißschuh my_syscall3(__NR_getrandom, &__stack_chk_guard, sizeof(__stack_chk_guard), 0);
4588fc7eb5SThomas Weißschuh /* a bit more randomness in case getrandom() fails, ensure the guard is never 0 */
4688fc7eb5SThomas Weißschuh if (__stack_chk_guard != (uintptr_t) &__stack_chk_guard)
477188d463SThomas Weißschuh __stack_chk_guard ^= (uintptr_t) &__stack_chk_guard;
487188d463SThomas Weißschuh }
49d7f16723SZhangjin Wu #else /* !defined(_NOLIBC_STACKPROTECTOR) */
__stack_chk_init(void)50dcb677c3SZhangjin Wu static void __stack_chk_init(void) {}
51818924d1SThomas Weißschuh #endif /* defined(_NOLIBC_STACKPROTECTOR) */
527188d463SThomas Weißschuh
53fddc8f81SThomas Weißschuh #endif /* _NOLIBC_STACKPROTECTOR_H */
54