mirror of
https://github.com/clearlinux/graphene.git
synced 2026-09-06 22:01:29 +00:00
[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:
@@ -11,3 +11,6 @@ ifeq ($(origin LD),default)
|
||||
LD = ld
|
||||
endif
|
||||
OBJCOPY ?= objcopy
|
||||
|
||||
CONFIG_PAL_STACK_PROTECTOR = n
|
||||
# CONFIG_PAL_STACK_PROTECTOR = y
|
||||
|
||||
@@ -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),)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 $@
|
||||
|
||||
@@ -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 ../../ $<
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
/.Makefile.stack-protector
|
||||
/asm-offsets.h
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 ../../ $<
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user