mirror of
https://github.com/clearlinux/graphene.git
synced 2026-09-05 21:31:36 +00:00
[LibOS] support stack protector with compile time option
Signed-off-by: Isaku Yamahata <isaku.yamahata@gmail.com>
This commit is contained in:
@@ -142,6 +142,7 @@ static inline PAL_HANDLE __open_shim_stdio (void)
|
||||
return shim_stdio;
|
||||
}
|
||||
|
||||
noreturn void* shim_init (int argc, void * args);
|
||||
noreturn void shim_terminate (int err);
|
||||
|
||||
/* assertions */
|
||||
|
||||
@@ -145,7 +145,15 @@ void put_thread (struct shim_thread * thread);
|
||||
void get_simple_thread (struct shim_simple_thread * thread);
|
||||
void put_simple_thread (struct shim_simple_thread * thread);
|
||||
|
||||
void __allocate_tls (__libc_tcb_t * tcb_location, bool user, struct shim_thread * thread);
|
||||
#ifdef ENABLE_STACK_PROTECTOR
|
||||
void allocate_tls (__libc_tcb_t * tcb_location, bool user, struct shim_thread * thread);
|
||||
#else
|
||||
static inline void allocate_tls (__libc_tcb_t * tcb_location, bool user, struct shim_thread * thread)
|
||||
{
|
||||
__allocate_tls(tcb_location, user, thread);
|
||||
}
|
||||
#endif
|
||||
void populate_tls (__libc_tcb_t * tcb_location, bool user);
|
||||
|
||||
void debug_setprefix (shim_tcb_t * tcb);
|
||||
|
||||
@@ -54,6 +54,10 @@ struct debug_buf;
|
||||
typedef struct shim_tcb shim_tcb_t;
|
||||
struct shim_tcb {
|
||||
uint64_t canary;
|
||||
#ifdef ENABLE_STACK_PROTECTOR
|
||||
#define STACK_PROTECTOR_CANARY_DEFAULT 0xbadbadbadbadUL
|
||||
uint64_t stack_protector_canary;
|
||||
#endif
|
||||
shim_tcb_t * self;
|
||||
struct shim_thread * tp;
|
||||
struct shim_context context;
|
||||
@@ -94,7 +98,15 @@ struct __libc_tcb_t
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
void __init_tcb (shim_tcb_t * tcb);
|
||||
#ifdef ENABLE_STACK_PROTECTOR
|
||||
void init_tcb (shim_tcb_t * tcb);
|
||||
#else
|
||||
static inline void init_tcb (shim_tcb_t * tcb)
|
||||
{
|
||||
__init_tcb(tcb);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline bool shim_tls_check_canary(void)
|
||||
{
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/.Makefile.stack-protector
|
||||
/libsysdb.so.cached
|
||||
/asm-offsets.h
|
||||
/generated-offsets.s
|
||||
|
||||
+21
-1
@@ -9,7 +9,7 @@ CFLAGS = -Wall -fPIC -std=c11 -Winline -Wwrite-strings \
|
||||
-fmerge-all-constants -Wstrict-prototypes \
|
||||
-Werror=implicit-function-declaration \
|
||||
$(cc-option, -Wnull-dereference) \
|
||||
-fno-stack-protector -fno-builtin -Wno-inline \
|
||||
-fno-builtin -Wno-inline \
|
||||
-I../include -I../../../Pal/lib -I../../../Pal/include/pal
|
||||
|
||||
EXTRAFLAGS = -Wextra
|
||||
@@ -69,6 +69,26 @@ ifeq ($(PROFILING), 1)
|
||||
CFLAGS += -DPROFILE
|
||||
endif
|
||||
|
||||
.Makefile.stack-protector: asm-offsets.h
|
||||
$(call cmd,makefile_stack_protector)
|
||||
|
||||
ifeq ($(CONFIG_SHIM_STACK_PROTECTOR),y)
|
||||
objs += shim_stack_protector
|
||||
CFLAGS-shim_stack_protector.o += -fno-stack-protector
|
||||
# gcc 8 or later is required for the folloings options
|
||||
# -mstack-protector-guard-offset, -mstack-protector-guard-reg
|
||||
include .Makefile.stack-protector
|
||||
$(addsuffix .o,$(objs)): .Makefile.stack-protector
|
||||
ASFLAGS += -DENABLE_STACK_PROTECTOR=1
|
||||
CFLAGS += -DENABLE_STACK_PROTECTOR=1
|
||||
ifneq ($(CONFIG_STACK_PROTECTOR_GUARD_OFFSET),)
|
||||
CFLAGS += -mstack-protector-guard-offset=$(CONFIG_STACK_PROTECTOR_GUARD_OFFSET)
|
||||
endif
|
||||
CFLAGS += -mstack-protector-guard-reg=%fs
|
||||
else
|
||||
CFLAGS += -fno-stack-protector
|
||||
endif
|
||||
|
||||
$(files_to_install): $(RUNTIME_DIR)/%: %
|
||||
$(call cmd,ln_sf)
|
||||
|
||||
|
||||
@@ -765,12 +765,15 @@ BEGIN_RS_FUNC(running_thread)
|
||||
thread->pal_handle = handle;
|
||||
} else {
|
||||
__libc_tcb_t * libc_tcb = thread->tcb;
|
||||
#ifdef ENABLE_STACK_PROTECTOR
|
||||
uint64_t stack_protector_canary = shim_libc_tcb()->shim_tcb.stack_protector_canary;
|
||||
#endif
|
||||
|
||||
if (libc_tcb) {
|
||||
shim_tcb_t * tcb = &libc_tcb->shim_tcb;
|
||||
assert(tcb->context.regs && tcb->context.regs->rsp);
|
||||
tcb->debug_buf = shim_get_tls()->debug_buf;
|
||||
allocate_tls(libc_tcb, thread->user_tcb, thread);
|
||||
__allocate_tls(libc_tcb, thread->user_tcb, thread);
|
||||
/* Temporarily disable preemption until the thread resumes. */
|
||||
__disable_preempt(tcb);
|
||||
debug_setprefix(tcb);
|
||||
@@ -785,12 +788,15 @@ BEGIN_RS_FUNC(running_thread)
|
||||
* user_tcb = false
|
||||
* in_vm = false
|
||||
*/
|
||||
init_tcb(&shim_libc_tcb()->shim_tcb);
|
||||
__init_tcb(&shim_libc_tcb()->shim_tcb);
|
||||
set_cur_thread(thread);
|
||||
}
|
||||
|
||||
thread->in_vm = thread->is_alive = true;
|
||||
thread->pal_handle = PAL_CB(first_thread);
|
||||
#ifdef ENABLE_STACK_PROTECTOR
|
||||
shim_libc_tcb()->shim_tcb.stack_protector_canary = stack_protector_canary;
|
||||
#endif
|
||||
}
|
||||
|
||||
DEBUG_RS("tid=%d", thread->tid);
|
||||
|
||||
@@ -16,5 +16,10 @@ void dummy(void)
|
||||
|
||||
/* definitions */
|
||||
DEFINE(RED_ZONE_SIZE, RED_ZONE_SIZE);
|
||||
|
||||
#ifdef ENABLE_STACK_PROTECTOR
|
||||
/* stack protector*/
|
||||
OFFSET_T(STACK_PROTECTOR_CANARY, __libc_tcb_t, shim_tcb.stack_protector_canary);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -71,9 +71,14 @@ void warn (const char *format, ...)
|
||||
}
|
||||
|
||||
|
||||
void __stack_chk_fail (void)
|
||||
#ifdef ENABLE_STACK_PROTECTOR
|
||||
noreturn void __stack_chk_fail (void)
|
||||
{
|
||||
__SYS_PRINTF("stack protector: libos stack is corrupted in %p",
|
||||
__builtin_return_address(0));
|
||||
__abort();
|
||||
}
|
||||
#endif
|
||||
|
||||
static int pal_errno_to_unix_errno [PAL_ERROR_BOUND + 1] = {
|
||||
/* reserved */ 0,
|
||||
@@ -183,7 +188,7 @@ char ** library_paths = NULL;
|
||||
struct shim_lock __master_lock;
|
||||
bool lock_enabled;
|
||||
|
||||
void init_tcb (shim_tcb_t * tcb)
|
||||
void __init_tcb (shim_tcb_t * tcb)
|
||||
{
|
||||
tcb->canary = SHIM_TLS_CANARY;
|
||||
tcb->self = tcb;
|
||||
@@ -193,6 +198,9 @@ void copy_tcb (shim_tcb_t * new_tcb, const shim_tcb_t * old_tcb)
|
||||
{
|
||||
memset(new_tcb, 0, sizeof(shim_tcb_t));
|
||||
new_tcb->canary = SHIM_TLS_CANARY;
|
||||
#ifdef ENABLE_STACK_PROTECTOR
|
||||
new_tcb->stack_protector_canary = old_tcb->stack_protector_canary;
|
||||
#endif
|
||||
new_tcb->self = new_tcb;
|
||||
new_tcb->tp = old_tcb->tp;
|
||||
memcpy(&new_tcb->context, &old_tcb->context, sizeof(struct shim_context));
|
||||
@@ -201,11 +209,11 @@ void copy_tcb (shim_tcb_t * new_tcb, const shim_tcb_t * old_tcb)
|
||||
}
|
||||
|
||||
/* This function is used to allocate tls before interpreter start running */
|
||||
void allocate_tls (__libc_tcb_t * tcb, bool user, struct shim_thread * thread)
|
||||
void __allocate_tls (__libc_tcb_t * tcb, bool user, struct shim_thread * thread)
|
||||
{
|
||||
assert(tcb);
|
||||
tcb->tcb = tcb;
|
||||
init_tcb(&tcb->shim_tcb);
|
||||
__init_tcb(&tcb->shim_tcb);
|
||||
|
||||
if (thread) {
|
||||
thread->tcb = tcb;
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/* Copyright 2019 Intel Corporation.
|
||||
Copyright 2019 Isaku Yamahata <isaku.yamahata at intel com>
|
||||
<isaku.yamahata at gmail com>
|
||||
This file is part of Graphene Library OS.
|
||||
|
||||
Graphene Library OS is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public License
|
||||
as published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
Graphene Library OS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <shim_internal.h>
|
||||
#include <shim_thread.h>
|
||||
#include <shim_tls.h>
|
||||
|
||||
#include "asm-offsets.h"
|
||||
|
||||
noreturn void __shim_init (int argc, void * args)
|
||||
{
|
||||
static uint64_t tcb[STACK_PROTECTOR_CANARY + 8 / sizeof(uint64_t)] =
|
||||
{ [STACK_PROTECTOR_CANARY / sizeof(uint64_t)] = STACK_PROTECTOR_CANARY_DEFAULT };
|
||||
DkSegmentRegister(PAL_SEGMENT_FS, &tcb);
|
||||
shim_init(argc, args);
|
||||
}
|
||||
|
||||
static void reset_stack_protector_canary (shim_tcb_t * tcb)
|
||||
{
|
||||
uint64_t stack_protector_canary;
|
||||
int ret = DkRandomBitsRead(&stack_protector_canary, sizeof(stack_protector_canary));
|
||||
if (ret < 0)
|
||||
stack_protector_canary = STACK_PROTECTOR_CANARY_DEFAULT;
|
||||
tcb->stack_protector_canary = stack_protector_canary;
|
||||
}
|
||||
|
||||
void init_tcb (shim_tcb_t * tcb)
|
||||
{
|
||||
__init_tcb(tcb);
|
||||
reset_stack_protector_canary(tcb);
|
||||
}
|
||||
|
||||
/* This function is used to allocate tls before interpreter start running */
|
||||
void allocate_tls (__libc_tcb_t * tcb, bool user, struct shim_thread * thread)
|
||||
{
|
||||
__allocate_tls(tcb, user, thread);
|
||||
reset_stack_protector_canary(&tcb->shim_tcb);
|
||||
}
|
||||
@@ -34,7 +34,11 @@ shim_start:
|
||||
# Required by System V AMD64 ABI.
|
||||
andq $~0xF, %rsp
|
||||
|
||||
#ifdef ENABLE_STACK_PROTECTOR
|
||||
callq *__shim_init@GOTPCREL(%rip)
|
||||
#else
|
||||
callq *shim_init@GOTPCREL(%rip)
|
||||
#endif
|
||||
|
||||
# TODO: Call initial %rdi to execute atexit callbacks.
|
||||
.cfi_endproc
|
||||
|
||||
@@ -14,3 +14,6 @@ OBJCOPY ?= objcopy
|
||||
|
||||
CONFIG_PAL_STACK_PROTECTOR = n
|
||||
# CONFIG_PAL_STACK_PROTECTOR = y
|
||||
|
||||
CONFIG_SHIM_STACK_PROTECTOR = n
|
||||
# CONFIG_SHIM_STACK_PROTECTOR = y
|
||||
|
||||
@@ -109,3 +109,10 @@ quiet_cmd_ld = [ $@ ]
|
||||
# OBJCOPY
|
||||
quiet_cmd_objcopy = [ $@ ]
|
||||
cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS-$@) $< $@
|
||||
|
||||
# stack protector
|
||||
quiet_cmd_makefile_stack_protector = [ $@ ]
|
||||
cmd_makefile_stack_protector = \
|
||||
(set -e; \
|
||||
awk '/\#define STACK_PROTECTOR_CANARY/{print "CONFIG_STACK_PROTECTOR_GUARD_OFFSET="$$3}' $^; \
|
||||
) > $@
|
||||
|
||||
Reference in New Issue
Block a user