Implement stack protection support

this adds kernel & libroot stack protector hooks. it uses /dev/random in userspace.
A configure option --enable-stack-protector is added to activate -fstack-protector
on selected system components (ATM apps, kits, servers).

Change-Id: If3a2920ba9aa0a85eaff4ba6778947f8c76ade31
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3895
Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
This commit is contained in:
Jérôme Duval 2021-05-01 15:24:28 +02:00
parent 409d65c0d6
commit 04be20a75a
12 changed files with 153 additions and 0 deletions

View File

@ -600,6 +600,16 @@ rule ArchitectureSetupWarnings architecture
}
}
rule EnableStackProtector dirTokens : scope {
# enable stack protector, if requested
if $(HAIKU_USE_STACK_PROTECTOR) = 1 {
AppendToConfigVar CCFLAGS : HAIKU_TOP $(dirTokens) :
-fstack-protector : $(scope) ;
AppendToConfigVar C++FLAGS : HAIKU_TOP $(dirTokens) :
-fstack-protector : $(scope) ;
}
}
# Work-around for GCC 2 problem -- despite -Wno-multichar it reports
# multichar warnings in headers/private/kernel/debugger_keymaps.h included
# by src/system/kernel/arch/x86/arch_debug_console.cpp.
@ -746,6 +756,12 @@ rule ArchitectureSetupWarnings architecture
EnableWerror src system libroot posix locale ;
EnableWerror src system libroot posix wchar ;
EnableWerror src system runtime_loader ;
EnableStackProtector src apps ;
EnableStackProtector src kits ;
EnableStackProtector src preferences ;
EnableStackProtector src servers ;
EnableStackProtector src system kernel ;
}

2
configure vendored
View File

@ -92,6 +92,7 @@ options:
--with-gdb <gdb sources dir>
specify the path to a GDB source dir, to build
GDB for each arch we build the cross-tools for.
--use-stack-protector Build with stack protection enabled
environment variables:
CC The host compiler. Defaults to "gcc".
@ -803,6 +804,7 @@ while [ $# -gt 0 ] ; do
--no-full-xattr)HAIKU_HOST_USE_XATTR=0; shift 1;;
--no-xattr) HAIKU_HOST_USE_XATTR_REF=0; shift 1;;
--with-gdb) gdbSources=$2; shift 2;;
--use-stack-protector) HAIKU_USE_STACK_PROTECTOR=1; shift 1;;
*) echo Invalid argument: \`$1\'; exit 1;;
esac
done

View File

@ -0,0 +1,12 @@
/*
* Copyright 2021, Jérôme Duval, jerome.duval@gmail.com.
* Distributed under the terms of the MIT License.
*/
#ifndef _KERNEL_STACK_PROTECTOR_H
#define _KERNEL_STACK_PROTECTOR_H
void stack_protector_init();
#endif /* _KERNEL_STACK_PROTECTOR_H */

View File

@ -55,6 +55,7 @@ void __reinit_pwd_backend_after_fork(void);
int32 __arch_get_stack_trace(addr_t* returnAddresses, int32 maxCount,
int32 skipFrames, addr_t stackBase, addr_t stackEnd);
void __init_stack_protector(void);
void __set_stack_protection(void);

View File

@ -47,6 +47,7 @@ KernelMergeObject kernel_core.o :
sem.cpp
shutdown.cpp
signal.cpp
stack_protector.cpp
system_info.cpp
smp.cpp
syscalls.cpp

View File

@ -51,6 +51,7 @@
#include <real_time_clock.h>
#include <sem.h>
#include <smp.h>
#include <stack_protector.h>
#include <system_profiler.h>
#include <team.h>
#include <timer.h>
@ -204,6 +205,8 @@ _start(kernel_args *bootKernelArgs, int currentCPU)
thread_init(&sKernelArgs);
TRACE("init kernel daemons\n");
kernel_daemon_init();
TRACE("init stack protector\n");
stack_protector_init();
arch_platform_init_post_thread(&sKernelArgs);
TRACE("init I/O interrupts\n");

View File

@ -0,0 +1,34 @@
/*
* Copyright 2021, Jérôme Duval, jerome.duval@gmail.com.
* Distributed under the terms of the MIT License.
*/
#include <sys/cdefs.h>
#include <SupportDefs.h>
#include <util/Random.h>
extern "C" {
long __stack_chk_guard;
void
__stack_chk_fail()
{
panic("stack smashing detected\n");
}
}
void
stack_protector_init()
{
__stack_chk_guard = secure_get_random<long>();
}

View File

@ -80,6 +80,7 @@ initialize_before(image_id imageID)
__init_heap();
__init_env_post_heap();
__init_pwd_backend();
__init_stack_protector();
__set_stack_protection();
}

View File

@ -34,6 +34,7 @@ for architectureObject in [ MultiArchSubDirSetup ] {
port.c
scheduler.c
sem.c
stack_protector.cpp
system_info.cpp
system_revision.c
team.c

View File

@ -0,0 +1,58 @@
/*
* Copyright 2021, Jérôme Duval, jerome.duval@gmail.com.
* Distributed under the terms of the MIT License.
*/
#include <fcntl.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/cdefs.h>
extern "C" {
long __stack_chk_guard = 0;
void
__init_stack_protector()
{
if (__stack_chk_guard != 0)
return;
bool done = false;
int fd = open("/dev/random", O_RDONLY, 0);
if (fd >= 0) {
done = read(fd, &__stack_chk_guard, sizeof(__stack_chk_guard))
== sizeof(__stack_chk_guard);
close(fd);
}
if (!done) {
((unsigned char *)(void *)__stack_chk_guard)[0] = 0;
((unsigned char *)(void *)__stack_chk_guard)[1] = 0;
((unsigned char *)(void *)__stack_chk_guard)[2] = '\n';
((unsigned char *)(void *)__stack_chk_guard)[3] = 0xff;
}
}
void
__stack_chk_fail()
{
sigset_t mask;
sigfillset(&mask);
sigdelset(&mask, SIGABRT);
sigprocmask(SIG_BLOCK, &mask, NULL);
abort();
}
}
#if __GNUC__ >= 4
extern "C" void __stack_chk_fail_local() __attribute__((visibility("hidden")));
__weak_reference(__stack_chk_fail, __stack_chk_fail_local);
#endif

View File

@ -28,6 +28,14 @@ SimpleTest get_cpu_num_test :
get_cpu_num_test.cpp
;
CCFLAGS += -fstack-protector ;
SimpleTest stack_protector_test :
stack_protector_test.c
;
# Tell Jam where to find these sources
SEARCH on [ FGristFiles
driver_settings.cpp

View File

@ -0,0 +1,16 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void get_input(char *data)
{
strcpy(data, "01234567");
}
int main(void)
{
char buffer[8];
get_input(buffer);
return buffer[0];
}