[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[UNIKRAFT PATCH] build: Add the option to compile the unikernel as PIE



From: DanielD1234 <danieldinca97@xxxxxxxxx>

This patch adds the option to compile the unikernel as
a position-independent executable so we can have ASLR.
If the unikernel is compiled as PIE, it cannot run on it's
own. A bootloader will be needed that will come in future patches.

Signed-off-by: DanielD1234 <danieldinca97@xxxxxxxxx>
---
 Config.uk                      |  9 +++++++++
 Makefile.uk                    | 14 +++++++++++---
 plat/common/x86/thread_start.S |  7 ++++---
 plat/kvm/x86/entry64.S         |  3 +++
 plat/kvm/x86/setup.c           |  8 ++++++++
 5 files changed, 35 insertions(+), 6 deletions(-)

diff --git a/Config.uk b/Config.uk
index 1d4143e..b18caf9 100644
--- a/Config.uk
+++ b/Config.uk
@@ -86,6 +86,15 @@ config OPTIMIZE_LTO
                will increase overall building time but creates more efficient
                Unikraft binaries.
 
+config ENABLE_PIE
+       bool "PIE - Postition-Independent Executable"
+       default n
+       help
+               Enables the unikernel to be compiled as a position-independent 
executable.
+               Note that certain parts of the entry64.S file will be 
eliminated, and the unikernel
+               will need to be loaded into memory from initrd by the 
bootloader (which will be compiled
+               separately).
+
 choice
        prompt "Debug information level"
        default DEBUG_SYMBOLS_LVL3
diff --git a/Makefile.uk b/Makefile.uk
index 4f1c764..76b6fc3 100644
--- a/Makefile.uk
+++ b/Makefile.uk
@@ -22,8 +22,8 @@ GOCINCLUDES  += -I$(CONFIG_UK_BASE)/include
 # Set the text and data sections to be readable and writable. Also,
 # do not page-align the data segment. If the output format supports
 # Unix style magic numbers, mark the output as OMAGIC.
-LIBLDFLAGS  += -nostdinc -nostdlib -Wl,--omagic -Wl,-r -Wl,-d 
-Wl,--build-id=none
-LDFLAGS     += -nostdinc -nostdlib -Wl,--omagic -Wl,--build-id=none
+LIBLDFLAGS  += -nostdinc -nostdlib -Wl,-r -Wl,-d -Wl,--build-id=none -no-pie
+LDFLAGS     += -nostdinc -nostdlib -Wl,--build-id=none
 
 COMPFLAGS-$(CONFIG_OPTIMIZE_NONE)         += -O0 -fno-optimize-sibling-calls 
-fno-tree-vectorize
 COMPFLAGS-$(CONFIG_OPTIMIZE_SIZE)         += -Os
@@ -50,9 +50,17 @@ ISR_ARCHFLAGS += -D__INTERRUPTSAFE__
 M4FLAGS      += -D __Unikraft__ -DUK_CODENAME="$(UK_CODENAME)"
 M4FLAGS      += -DUK_VERSION=$(UK_VERSION).$(UK_SUBVERSION)
 
+ifeq ($(CONFIG_ENABLE_PIE),y)
+COMPFLAGS-$(call gcc_version_ge,6,1)   += -fPIC
+LDFLAGS-$(call gcc_version_ge,6,1)     += -static-pie
+else
 # If GCC supports "-no-pie" flag, we will add this flag to link flags to
 # override "pie" option, because some distributions will set
 # "--enable-default-pie" by default.
 COMPFLAGS-$(call gcc_version_ge,6,1)   += -no-pie
-LIBLDFLAGS-$(call gcc_version_ge,6,1)  += -no-pie
 LDFLAGS-$(call gcc_version_ge,6,1)     += -no-pie
+# --omagic option is incompatible with the -pie option, so add them when -pie
+# is not enabled
+LIBLDFLAGS  += -Wl,--omagic
+LDFLAGS     += -Wl,--omagic
+endif
diff --git a/plat/common/x86/thread_start.S b/plat/common/x86/thread_start.S
index b23666a..360ca91 100644
--- a/plat/common/x86/thread_start.S
+++ b/plat/common/x86/thread_start.S
@@ -36,7 +36,7 @@ ENTRY(asm_thread_starter)
        pushq $0
        xorq %rbp,%rbp
        call *%rbx
-       call uk_sched_thread_exit
+       call *uk_sched_thread_exit@GOTPCREL(%rip)
 
 ENTRY(asm_ctx_start)
        mov %rdi, %rsp      /* set SP */
@@ -52,10 +52,11 @@ ENTRY(asm_sw_ctx_switch)
        pushq %r15
        movq %rsp, OFFSETOF_SW_CTX_SP(%rdi)       /* save ESP */
        movq OFFSETOF_SW_CTX_SP(%rsi), %rsp       /* restore ESP */
-       movq $1f, OFFSETOF_SW_CTX_IP(%rdi)        /* save EIP */
+       lea .Lreturn(%rip), %rbx
+       movq %rbx, OFFSETOF_SW_CTX_IP(%rdi)       /* save EIP */
        pushq OFFSETOF_SW_CTX_IP(%rsi)            /* restore EIP */
        ret
-1:
+.Lreturn:
        popq %r15
        popq %r14
        popq %r13
diff --git a/plat/kvm/x86/entry64.S b/plat/kvm/x86/entry64.S
index 274ab0b..70b23e5 100644
--- a/plat/kvm/x86/entry64.S
+++ b/plat/kvm/x86/entry64.S
@@ -30,6 +30,7 @@
 #include <x86/cpu_defs.h>
 #include <kvm-x86/traps.h>
 #include <kvm-x86/multiboot_defs.h>
+#include <uk/config.h>
 
 #define ENTRY(x) .globl x; .type x,%function; x:
 #define END(x)   .size x, . - x
@@ -37,6 +38,7 @@
 #define MYMULTIBOOT_FLAGS \
     (MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_AOUT_KLUDGE)
 
+#ifndef CONFIG_ENABLE_PIE
 .section .data.boot
 
 .align 4
@@ -236,6 +238,7 @@ nofsgsbase:
        cli
        hlt
 END(_libkvmplat_start64)
+#endif
 
 .text
 ENTRY(_libkvmplat_newstack)
diff --git a/plat/kvm/x86/setup.c b/plat/kvm/x86/setup.c
index 9c7a93a..c8ee841 100644
--- a/plat/kvm/x86/setup.c
+++ b/plat/kvm/x86/setup.c
@@ -40,6 +40,7 @@
 #include <uk/plat/console.h>
 #include <uk/assert.h>
 #include <uk/essentials.h>
+#include <uk/config.h>
 
 #define PLATFORM_MEM_START 0x100000
 #define PLATFORM_MAX_MEM_ADDR 0x40000000
@@ -274,7 +275,14 @@ void _libkvmplat_entry(void *arg)
         */
        _mb_get_cmdline(mi);
        _mb_init_mem(mi);
+       /*
+        * If the unikernel is compiled as PIE and we want to run it with ASLR, 
the
+        * unikernel code will first be placed in the initrd section and then 
will be
+        * relocated by the bootloader. After the relocation we will not have 
an initrd.
+        */
+       #ifndef CONFIG_ENABLE_PIE
        _mb_init_initrd(mi);
+       #endif
 
        if (_libkvmplat_cfg.initrd.len)
                uk_pr_info("        initrd: %p\n",
-- 
2.17.1




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.