[LibOS] support stack protector with compile time option

Signed-off-by: Isaku Yamahata <isaku.yamahata@gmail.com>
This commit is contained in:
Isaku Yamahata
2019-07-24 17:46:59 -07:00
parent e747b80b30
commit efb19cfa24
12 changed files with 136 additions and 7 deletions
+1
View File
@@ -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 */
+8
View File
@@ -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);
+12
View File
@@ -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
View File
@@ -1,3 +1,4 @@
/.Makefile.stack-protector
/libsysdb.so.cached
/asm-offsets.h
/generated-offsets.s
+21 -1
View File
@@ -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)
+8 -2
View File
@@ -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);
+5
View File
@@ -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
}
+12 -4
View File
@@ -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;
+54
View File
@@ -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);
}
+4
View File
@@ -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
+3
View File
@@ -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
+7
View File
@@ -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}' $^; \
) > $@