[Pal/Linux] enable stack protector

enable stack protector for Pal/Linux.
for other Pal, enabling stack protector results in error.

Signed-off-by: Isaku Yamahata <isaku.yamahata@gmail.com>
This commit is contained in:
Isaku Yamahata
2019-07-24 17:46:28 -07:00
parent a45f3b8196
commit cdff566051
16 changed files with 189 additions and 41 deletions
+3
View File
@@ -11,3 +11,6 @@ ifeq ($(origin LD),default)
LD = ld
endif
OBJCOPY ?= objcopy
CONFIG_PAL_STACK_PROTECTOR = n
# CONFIG_PAL_STACK_PROTECTOR = y
+5
View File
@@ -12,6 +12,11 @@ include ../src/host/$(PAL_HOST)/Makefile.am
CFLAGS += -I. -I../include -I../src
# TODO: enable stack protector pal/lib. security/Linux/libpal_sec.so is blocker.
# Makefile.am overwrites CFLAGS. defining CFLAGS before Makefile.am
# may not have effects.
CFLAGS += -fno-stack-protector
# Include host_endian.h from either the host-specific directory,
# or directly under the target directory.
ifeq ($(target),)
+21
View File
@@ -56,6 +56,27 @@ CFLAGS += -DDEBUG
endif
export DEBUG
$(HOST_DIR)/asm-offsets.h:
$(MAKE) -C $(HOST_DIR) $(notdir $@)
$(HOST_DIR)/.Makefile.stack-protector: $(HOST_DIR)/asm-offsets.h
$(call cmd,makefile_stack_protector)
ifeq ($(CONFIG_PAL_STACK_PROTECTOR),y)
include $(HOST_DIR)/.Makefile.stack-protector
$(addsuffix .o,$(objs)): $(HOST_DIR)/.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=%gs
else
CFLAGS += -fno-stack-protector
endif
# Install Targets (all in RUNTIME_DIR):
# pal-{Host Name}: loader for PAL (as an executable)
# libpal-{Host Name}.so: dynamic-linking library
+9
View File
@@ -32,6 +32,15 @@
#include <sysdeps/generic/ldsodefs.h>
#include <elf/elf.h>
#ifdef ENABLE_STACK_PROTECTOR
void __stack_chk_fail(void)
{
printf("stack protector: Pal stack is corrupted in %p\n",
__builtin_return_address(0));
_DkThreadExit();
}
#endif
PAL_CONTROL __pal_control;
PAL_CONTROL * pal_control_addr (void)
+4
View File
@@ -25,6 +25,10 @@ CFLAGS += -DDEBUG
export DEBUG
endif
ifeq ($(CONFIG_PAL_STACK_PROTECTOR),y)
$(error CONFIG_PAL_STACK_PROTECTOR is not supported)
endif
pal-gdb: pal-gdb.template
sed -e 's:\$$(PAL_DIR):$(PWD):g' $< > $@
chmod 755 $@
+4
View File
@@ -30,6 +30,10 @@ ASFLAGS += -DDEBUG
export DEBUG
endif
ifeq ($(CONFIG_PAL_STACK_PROTECTOR),y)
$(error CONFIG_PAL_STACK_PROTECTOR is not supported)
endif
../../host_endian.h: host_endian.h
$(MAKE) -C ../../ $<
+2
View File
@@ -0,0 +1,2 @@
/.Makefile.stack-protector
/asm-offsets.h
+20 -1
View File
@@ -16,7 +16,7 @@ defs = -DIN_PAL -DPAL_DIR=$(PAL_DIR) -DRUNTIME_DIR=$(RUNTIME_DIR)
CFLAGS += $(defs)
ASFLAGS += $(defs)
objs = $(addprefix db_,files devices pipes sockets streams memory threading \
mutex events process object main rtld misc ipc \
mutex events process object main rtld misc ipc stack_protector \
exception) manifest clone-x86_64 gettimeofday-x86_64
graphene_lib = .lib/graphene-lib.a
headers = $(wildcard *.h) $(wildcard ../../*.h) $(wildcard ../../../lib/*.h)
@@ -30,6 +30,25 @@ CFLAGS += -DDEBUG
export DEBUG
endif
.Makefile.stack-protector: asm-offsets.h
$(call cmd,makefile_stack_protector)
CFLAGS-db_stack_protector.o += -fno-stack-protector
ifeq ($(CONFIG_PAL_STACK_PROTECTOR),y)
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=%gs
else
CFLAGS += -fno-stack-protector
endif
libpal-Linux.a: $(addsuffix .o,$(objs)) $(graphene_lib)
$(call cmd,ar_a_o)
+1 -1
View File
@@ -3,7 +3,7 @@ HOST_DIR = host/$(PAL_HOST)
SEC_DIR = security/$(PAL_HOST)
CFLAGS = -Wall -fPIC -O2 -std=c11 -U_FORTIFY_SOURCE \
-fno-stack-protector -fno-builtin
-fno-builtin
EXTRAFLAGS = -Wextra $(call cc-option,-Wnull-dereference)
+5
View File
@@ -37,6 +37,7 @@
#include <elf/elf.h>
#include <sysdeps/generic/ldsodefs.h>
#ifndef ENABLE_STACK_PROTECTOR
/* At the begining of entry point, rsp starts at argc, then argvs,
envps and auxvs. Here we store rsp to rdi, so it will not be
messed up by function calls */
@@ -45,6 +46,7 @@ __asm__ (".global pal_start \n"
"pal_start: \n"
" movq %rsp, %rdi \n"
" call pal_linux_main \n");
#endif
#define RTLD_BOOTSTRAP
@@ -245,6 +247,9 @@ void pal_linux_main (void * args)
tcb->alt_stack = alt_stack; // Stack bottom
tcb->callback = NULL;
tcb->param = NULL;
#if ENABLE_STACK_PROTECTOR
tcb->stack_protector_canary = STACK_PROTECTOR_CANARY_DEFAULT;
#endif
pal_thread_init(tcb);
setup_pal_map(&pal_map);
+86
View File
@@ -0,0 +1,86 @@
/* 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 "pal_linux.h"
#include "pal_internal.h"
#include <linux/signal.h>
#include <asm/prctl.h>
#ifdef ENABLE_STACK_PROTECTOR
/* At the begining of entry point, rsp starts at argc, then argvs,
envps and auxvs. Here we store rsp to rdi, so it will not be
messed up by function calls */
__asm__ (
".global pal_start \n"
".type pal_start,@function \n"
"pal_start: \n"
" movq %rsp, %rdi \n"
" call __pal_linux_main \n");
void __pal_linux_main (void * args)
{
static PAL_TCB tcb = {
.stack_protector_canary = STACK_PROTECTOR_CANARY_DEFAULT
};
int ret = INLINE_SYSCALL(arch_prctl, 2, ARCH_SET_GS, &tcb);
if (IS_ERR(ret)) {
while (true) {
/* do nothing */
}
}
pal_linux_main(args);
}
#endif
/*
* pal_thread_init(): An initialization wrapper of a newly-created thread (including
* the first thread). This function accepts a TCB pointer to be set to the GS register
* of the thread. The rest of the TCB is used as the alternative stack for signal
* handling.
*/
int pal_thread_init (void * tcbptr)
{
PAL_TCB * tcb = tcbptr;
int ret;
ret = INLINE_SYSCALL(arch_prctl, 2, ARCH_SET_GS, tcb);
if (IS_ERR(ret))
return -ERRNO(ret);
if (tcb->alt_stack) {
// Align stack to 16 bytes
void * alt_stack_top = (void *) ((uint64_t) tcb & ~15);
assert(alt_stack_top > tcb->alt_stack);
stack_t ss;
ss.ss_sp = alt_stack_top;
ss.ss_flags = 0;
ss.ss_size = alt_stack_top - tcb->alt_stack;
ret = INLINE_SYSCALL(sigaltstack, 2, &ss, NULL);
if (IS_ERR(ret))
return -ERRNO(ret);
}
if (tcb->callback)
return (*tcb->callback) (tcb->param);
return 0;
}
+7 -35
View File
@@ -42,41 +42,6 @@
#include <asm/prctl.h>
#endif
/*
* pal_thread_init(): An initialization wrapper of a newly-created thread (including
* the first thread). This function accepts a TCB pointer to be set to the GS register
* of the thread. The rest of the TCB is used as the alternative stack for signal
* handling.
*/
int pal_thread_init (void * tcbptr)
{
PAL_TCB * tcb = tcbptr;
int ret;
ret = INLINE_SYSCALL(arch_prctl, 2, ARCH_SET_GS, tcb);
if (IS_ERR(ret))
return -ERRNO(ret);
if (tcb->alt_stack) {
// Align stack to 16 bytes
void * alt_stack_top = (void *) ((uint64_t) tcb & ~15);
assert(alt_stack_top > tcb->alt_stack);
stack_t ss;
ss.ss_sp = alt_stack_top;
ss.ss_flags = 0;
ss.ss_size = alt_stack_top - tcb->alt_stack;
ret = INLINE_SYSCALL(sigaltstack, 2, &ss, NULL);
if (IS_ERR(ret))
return -ERRNO(ret);
}
if (tcb->callback)
return (*tcb->callback) (tcb->param);
return 0;
}
/* _DkThreadCreate for internal use. Create an internal thread
inside the current process. The arguments callback and param
specify the starting function and parameters */
@@ -105,6 +70,13 @@ int _DkThreadCreate (PAL_HANDLE * handle, int (*callback) (void *),
tcb->alt_stack = child_stack; // Stack bottom
tcb->callback = callback;
tcb->param = (void *) param;
#ifdef ENABLE_STACK_PROTECTOR
uint64_t canary;
ret = _DkRandomBitsRead(&canary, sizeof(canary));
if (ret < 0)
canary = STACK_PROTECTOR_CANARY_DEFAULT;
tcb->stack_protector_canary = canary;
#endif
/* align child_stack to 16 */
child_stack = ALIGN_DOWN_PTR(child_stack, 16);
+14
View File
@@ -0,0 +1,14 @@
#include <stddef.h>
#include <generated-offsets-build.h>
#include "pal_linux.h"
void dummy(void)
{
/* pal_linux.h */
#ifdef ENABLE_STACK_PROTECTOR
OFFSET_T(STACK_PROTECTOR_CANARY, PAL_TCB, stack_protector_canary);
#endif
}
+4
View File
@@ -187,6 +187,10 @@ struct event_queue {
DEFINE_LISTP(event_queue);
typedef struct pal_tcb {
struct pal_tcb * self;
#ifdef ENABLE_STACK_PROTECTOR
#define STACK_PROTECTOR_CANARY_DEFAULT 0x2bad2bad2bad2badUL
uint64_t stack_protector_canary;
#endif
int pending_event;
LISTP_TYPE(event_queue) pending_queue;
PAL_HANDLE handle;
+4
View File
@@ -23,6 +23,10 @@ CFLAGS += -DDEBUG
export DEBUG
endif
ifeq ($(CONFIG_PAL_STACK_PROTECTOR),y)
$(error CONFIG_PAL_STACK_PROTECTOR is not supported)
endif
../../host_endian.h: host_endian.h
$(MAKE) -C ../../ $<
-4
View File
@@ -28,10 +28,6 @@
#include "pal_error.h"
#include "api.h"
void __stack_chk_fail(void)
{
}
/* must implement "pal_start", and call "pal_main" inside */
void pal_start (void);