mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 13:57:33 -04:00
We are using the getrandom syscall to get a random seed for the
stack protector canary but we are calling it with no flags which means
it'll block until there is some real randomness to return.
This means that if the crng is not ready yet program startup will
block and if you are unlucky that could be for a long time and
look like the program has crashed.
Even if the call to getrandom does not yield any random data,
we will still initialize the canary.
Fixes: 7188d4637e ("tools/nolibc: add support for stack protector")
Signed-off-by: Daniel Palmer <daniel@thingy.jp>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260522090726.726985-1-daniel@thingy.jp
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
57 lines
1.6 KiB
C
57 lines
1.6 KiB
C
/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
|
|
/*
|
|
* Stack protector support for NOLIBC
|
|
* Copyright (C) 2023 Thomas Weißschuh <linux@weissschuh.net>
|
|
*/
|
|
|
|
#ifndef _NOLIBC_STACKPROTECTOR_H
|
|
#define _NOLIBC_STACKPROTECTOR_H
|
|
|
|
#include "compiler.h"
|
|
|
|
#ifndef NOLIBC_NO_RUNTIME
|
|
#if defined(_NOLIBC_STACKPROTECTOR)
|
|
|
|
#include "sys.h"
|
|
#include "stdlib.h"
|
|
|
|
/* The functions in this header are using raw syscall macros to avoid
|
|
* triggering stack protector errors themselves
|
|
*/
|
|
|
|
void __stack_chk_fail(void);
|
|
__attribute__((weak,used,noreturn,section(".text.nolibc_stack_chk")))
|
|
void __stack_chk_fail(void)
|
|
{
|
|
pid_t pid;
|
|
__nolibc_syscall3(__NR_write, STDERR_FILENO, "!!Stack smashing detected!!\n", 28);
|
|
pid = __nolibc_syscall0(__NR_getpid);
|
|
__nolibc_syscall2(__NR_kill, pid, SIGABRT);
|
|
for (;;);
|
|
}
|
|
|
|
void __stack_chk_fail_local(void);
|
|
__attribute__((weak,noreturn,section(".text.nolibc_stack_chk")))
|
|
void __stack_chk_fail_local(void)
|
|
{
|
|
__stack_chk_fail();
|
|
}
|
|
|
|
__attribute__((weak,used,section(".data.nolibc_stack_chk")))
|
|
uintptr_t __stack_chk_guard;
|
|
|
|
static __nolibc_no_stack_protector void __stack_chk_init(void)
|
|
{
|
|
__nolibc_syscall3(__NR_getrandom, &__stack_chk_guard, sizeof(__stack_chk_guard),
|
|
GRND_INSECURE | GRND_NONBLOCK);
|
|
/* a bit more randomness in case getrandom() fails, ensure the guard is never 0 */
|
|
if (__stack_chk_guard != (uintptr_t) &__stack_chk_guard)
|
|
__stack_chk_guard ^= (uintptr_t) &__stack_chk_guard;
|
|
}
|
|
#else /* !defined(_NOLIBC_STACKPROTECTOR) */
|
|
static void __stack_chk_init(void) {}
|
|
#endif /* defined(_NOLIBC_STACKPROTECTOR) */
|
|
#endif /* NOLIBC_NO_RUNTIME */
|
|
|
|
#endif /* _NOLIBC_STACKPROTECTOR_H */
|