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 <[email protected]>
This commit is contained in:
@@ -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
|
# Work-around for GCC 2 problem -- despite -Wno-multichar it reports
|
||||||
# multichar warnings in headers/private/kernel/debugger_keymaps.h included
|
# multichar warnings in headers/private/kernel/debugger_keymaps.h included
|
||||||
# by src/system/kernel/arch/x86/arch_debug_console.cpp.
|
# 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 locale ;
|
||||||
EnableWerror src system libroot posix wchar ;
|
EnableWerror src system libroot posix wchar ;
|
||||||
EnableWerror src system runtime_loader ;
|
EnableWerror src system runtime_loader ;
|
||||||
|
|
||||||
|
EnableStackProtector src apps ;
|
||||||
|
EnableStackProtector src kits ;
|
||||||
|
EnableStackProtector src preferences ;
|
||||||
|
EnableStackProtector src servers ;
|
||||||
|
EnableStackProtector src system kernel ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ options:
|
|||||||
--with-gdb <gdb sources dir>
|
--with-gdb <gdb sources dir>
|
||||||
specify the path to a GDB source dir, to build
|
specify the path to a GDB source dir, to build
|
||||||
GDB for each arch we build the cross-tools for.
|
GDB for each arch we build the cross-tools for.
|
||||||
|
--use-stack-protector Build with stack protection enabled
|
||||||
|
|
||||||
environment variables:
|
environment variables:
|
||||||
CC The host compiler. Defaults to "gcc".
|
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-full-xattr)HAIKU_HOST_USE_XATTR=0; shift 1;;
|
||||||
--no-xattr) HAIKU_HOST_USE_XATTR_REF=0; shift 1;;
|
--no-xattr) HAIKU_HOST_USE_XATTR_REF=0; shift 1;;
|
||||||
--with-gdb) gdbSources=$2; shift 2;;
|
--with-gdb) gdbSources=$2; shift 2;;
|
||||||
|
--use-stack-protector) HAIKU_USE_STACK_PROTECTOR=1; shift 1;;
|
||||||
*) echo Invalid argument: \`$1\'; exit 1;;
|
*) echo Invalid argument: \`$1\'; exit 1;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021, Jérôme Duval, [email protected].
|
||||||
|
* 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 */
|
||||||
@@ -55,6 +55,7 @@ void __reinit_pwd_backend_after_fork(void);
|
|||||||
int32 __arch_get_stack_trace(addr_t* returnAddresses, int32 maxCount,
|
int32 __arch_get_stack_trace(addr_t* returnAddresses, int32 maxCount,
|
||||||
int32 skipFrames, addr_t stackBase, addr_t stackEnd);
|
int32 skipFrames, addr_t stackBase, addr_t stackEnd);
|
||||||
|
|
||||||
|
void __init_stack_protector(void);
|
||||||
void __set_stack_protection(void);
|
void __set_stack_protection(void);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ KernelMergeObject kernel_core.o :
|
|||||||
sem.cpp
|
sem.cpp
|
||||||
shutdown.cpp
|
shutdown.cpp
|
||||||
signal.cpp
|
signal.cpp
|
||||||
|
stack_protector.cpp
|
||||||
system_info.cpp
|
system_info.cpp
|
||||||
smp.cpp
|
smp.cpp
|
||||||
syscalls.cpp
|
syscalls.cpp
|
||||||
|
|||||||
@@ -51,6 +51,7 @@
|
|||||||
#include <real_time_clock.h>
|
#include <real_time_clock.h>
|
||||||
#include <sem.h>
|
#include <sem.h>
|
||||||
#include <smp.h>
|
#include <smp.h>
|
||||||
|
#include <stack_protector.h>
|
||||||
#include <system_profiler.h>
|
#include <system_profiler.h>
|
||||||
#include <team.h>
|
#include <team.h>
|
||||||
#include <timer.h>
|
#include <timer.h>
|
||||||
@@ -204,6 +205,8 @@ _start(kernel_args *bootKernelArgs, int currentCPU)
|
|||||||
thread_init(&sKernelArgs);
|
thread_init(&sKernelArgs);
|
||||||
TRACE("init kernel daemons\n");
|
TRACE("init kernel daemons\n");
|
||||||
kernel_daemon_init();
|
kernel_daemon_init();
|
||||||
|
TRACE("init stack protector\n");
|
||||||
|
stack_protector_init();
|
||||||
arch_platform_init_post_thread(&sKernelArgs);
|
arch_platform_init_post_thread(&sKernelArgs);
|
||||||
|
|
||||||
TRACE("init I/O interrupts\n");
|
TRACE("init I/O interrupts\n");
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021, Jérôme Duval, [email protected].
|
||||||
|
* 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>();
|
||||||
|
}
|
||||||
|
|
||||||
@@ -80,6 +80,7 @@ initialize_before(image_id imageID)
|
|||||||
__init_heap();
|
__init_heap();
|
||||||
__init_env_post_heap();
|
__init_env_post_heap();
|
||||||
__init_pwd_backend();
|
__init_pwd_backend();
|
||||||
|
__init_stack_protector();
|
||||||
__set_stack_protection();
|
__set_stack_protection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
|||||||
port.c
|
port.c
|
||||||
scheduler.c
|
scheduler.c
|
||||||
sem.c
|
sem.c
|
||||||
|
stack_protector.cpp
|
||||||
system_info.cpp
|
system_info.cpp
|
||||||
system_revision.c
|
system_revision.c
|
||||||
team.c
|
team.c
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021, Jérôme Duval, [email protected].
|
||||||
|
* 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
|
||||||
@@ -28,6 +28,14 @@ SimpleTest get_cpu_num_test :
|
|||||||
get_cpu_num_test.cpp
|
get_cpu_num_test.cpp
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
CCFLAGS += -fstack-protector ;
|
||||||
|
SimpleTest stack_protector_test :
|
||||||
|
stack_protector_test.c
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Tell Jam where to find these sources
|
# Tell Jam where to find these sources
|
||||||
SEARCH on [ FGristFiles
|
SEARCH on [ FGristFiles
|
||||||
driver_settings.cpp
|
driver_settings.cpp
|
||||||
|
|||||||
@@ -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];
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user