Commit ba7dd857 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'x86_sgx_for_6.8' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 SGX updates from Dave Hansen:
 "This time, these are entirely confined to SGX selftests fixes.

  The mini SGX enclave built by the selftests has garnered some
  attention because it stands alone and does not need the sizable
  infrastructure of the official SGX SDK. I think that's why folks are
  suddently interested in cleaning it up.

   - Clean up selftest compilation issues, mostly from non-gcc compilers

   - Avoid building selftests when not on x86"

* tag 'x86_sgx_for_6.8' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  selftests/sgx: Skip non X86_64 platform
  selftests/sgx: Remove incomplete ABI sanitization code in test enclave
  selftests/sgx: Discard unsupported ELF sections
  selftests/sgx: Ensure expected location of test enclave buffer
  selftests/sgx: Ensure test enclave buffer is entirely preserved
  selftests/sgx: Fix linker script asserts
  selftests/sgx: Handle relocations in test enclave
  selftests/sgx: Produce static-pie executable for test enclave
  selftests/sgx: Remove redundant enclave base address save/restore
  selftests/sgx: Specify freestanding environment for enclave compilation
  selftests/sgx: Separate linker options
  selftests/sgx: Include memory clobber for inline asm in test enclave
  selftests/sgx: Fix uninitialized pointer dereferences in encl_get_entry
  selftests/sgx: Fix uninitialized pointer dereference in error path
parents b0d326da 981cf568
......@@ -12,14 +12,16 @@ OBJCOPY := $(CROSS_COMPILE)objcopy
endif
INCLUDES := -I$(top_srcdir)/tools/include
HOST_CFLAGS := -Wall -Werror -g $(INCLUDES) -fPIC -z noexecstack
ENCL_CFLAGS := -Wall -Werror -static -nostdlib -nostartfiles -fPIC \
HOST_CFLAGS := -Wall -Werror -g $(INCLUDES) -fPIC
HOST_LDFLAGS := -z noexecstack -lcrypto
ENCL_CFLAGS += -Wall -Werror -static-pie -nostdlib -ffreestanding -fPIE \
-fno-stack-protector -mrdrnd $(INCLUDES)
ENCL_LDFLAGS := -Wl,-T,test_encl.lds,--build-id=none
ifeq ($(CAN_BUILD_X86_64), 1)
TEST_CUSTOM_PROGS := $(OUTPUT)/test_sgx
TEST_FILES := $(OUTPUT)/test_encl.elf
ifeq ($(CAN_BUILD_X86_64), 1)
all: $(TEST_CUSTOM_PROGS) $(OUTPUT)/test_encl.elf
endif
......@@ -28,7 +30,7 @@ $(OUTPUT)/test_sgx: $(OUTPUT)/main.o \
$(OUTPUT)/sigstruct.o \
$(OUTPUT)/call.o \
$(OUTPUT)/sign_key.o
$(CC) $(HOST_CFLAGS) -o $@ $^ -lcrypto
$(CC) $(HOST_CFLAGS) -o $@ $^ $(HOST_LDFLAGS)
$(OUTPUT)/main.o: main.c
$(CC) $(HOST_CFLAGS) -c $< -o $@
......@@ -45,8 +47,8 @@ $(OUTPUT)/call.o: call.S
$(OUTPUT)/sign_key.o: sign_key.S
$(CC) $(HOST_CFLAGS) -c $< -o $@
$(OUTPUT)/test_encl.elf: test_encl.lds test_encl.c test_encl_bootstrap.S
$(CC) $(ENCL_CFLAGS) -T $^ -o $@ -Wl,--build-id=none
$(OUTPUT)/test_encl.elf: test_encl.c test_encl_bootstrap.S
$(CC) $(ENCL_CFLAGS) $^ -o $@ $(ENCL_LDFLAGS)
EXTRA_CLEAN := \
$(OUTPUT)/test_encl.elf \
......
......@@ -13,6 +13,8 @@
#define __aligned(x) __attribute__((__aligned__(x)))
#define __packed __attribute__((packed))
#define __used __attribute__((used))
#define __section(x)__attribute__((__section__(x)))
#include "../../../../arch/x86/include/asm/sgx.h"
#include "../../../../arch/x86/include/asm/enclu.h"
......
......@@ -136,11 +136,11 @@ static bool encl_ioc_add_pages(struct encl *encl, struct encl_segment *seg)
*/
uint64_t encl_get_entry(struct encl *encl, const char *symbol)
{
Elf64_Sym *symtab = NULL;
char *sym_names = NULL;
Elf64_Shdr *sections;
Elf64_Sym *symtab;
Elf64_Ehdr *ehdr;
char *sym_names;
int num_sym;
int num_sym = 0;
int i;
ehdr = encl->bin;
......@@ -161,6 +161,9 @@ uint64_t encl_get_entry(struct encl *encl, const char *symbol)
}
}
if (!symtab || !sym_names)
return 0;
for (i = 0; i < num_sym; i++) {
Elf64_Sym *sym = &symtab[i];
......
......@@ -318,9 +318,9 @@ bool encl_measure(struct encl *encl)
struct sgx_sigstruct *sigstruct = &encl->sigstruct;
struct sgx_sigstruct_payload payload;
uint8_t digest[SHA256_DIGEST_LENGTH];
EVP_MD_CTX *ctx = NULL;
unsigned int siglen;
RSA *key = NULL;
EVP_MD_CTX *ctx;
int i;
memset(sigstruct, 0, sizeof(*sigstruct));
......@@ -384,7 +384,8 @@ bool encl_measure(struct encl *encl)
return true;
err:
EVP_MD_CTX_destroy(ctx);
if (ctx)
EVP_MD_CTX_destroy(ctx);
RSA_free(key);
return false;
}
......@@ -5,11 +5,12 @@
#include "defines.h"
/*
* Data buffer spanning two pages that will be placed first in .data
* segment. Even if not used internally the second page is needed by
* external test manipulating page permissions.
* Data buffer spanning two pages that will be placed first in the .data
* segment via the linker script. Even if not used internally the second page
* is needed by external test manipulating page permissions, so mark
* encl_buffer as "used" to make sure it is entirely preserved by the compiler.
*/
static uint8_t encl_buffer[8192] = { 1 };
static uint8_t __used __section(".data.encl_buffer") encl_buffer[8192] = { 1 };
enum sgx_enclu_function {
EACCEPT = 0x5,
......@@ -24,10 +25,11 @@ static void do_encl_emodpe(void *_op)
secinfo.flags = op->flags;
asm volatile(".byte 0x0f, 0x01, 0xd7"
:
: /* no outputs */
: "a" (EMODPE),
"b" (&secinfo),
"c" (op->epc_addr));
"c" (op->epc_addr)
: "memory" /* read from secinfo pointer */);
}
static void do_encl_eaccept(void *_op)
......@@ -42,7 +44,8 @@ static void do_encl_eaccept(void *_op)
: "=a" (rax)
: "a" (EACCEPT),
"b" (&secinfo),
"c" (op->epc_addr));
"c" (op->epc_addr)
: "memory" /* read from secinfo pointer */);
op->ret = rax;
}
......@@ -119,21 +122,41 @@ static void do_encl_op_nop(void *_op)
}
/*
* Symbol placed at the start of the enclave image by the linker script.
* Declare this extern symbol with visibility "hidden" to ensure the compiler
* does not access it through the GOT and generates position-independent
* addressing as __encl_base(%rip), so we can get the actual enclave base
* during runtime.
*/
extern const uint8_t __attribute__((visibility("hidden"))) __encl_base;
typedef void (*encl_op_t)(void *);
static const encl_op_t encl_op_array[ENCL_OP_MAX] = {
do_encl_op_put_to_buf,
do_encl_op_get_from_buf,
do_encl_op_put_to_addr,
do_encl_op_get_from_addr,
do_encl_op_nop,
do_encl_eaccept,
do_encl_emodpe,
do_encl_init_tcs_page,
};
void encl_body(void *rdi, void *rsi)
{
const void (*encl_op_array[ENCL_OP_MAX])(void *) = {
do_encl_op_put_to_buf,
do_encl_op_get_from_buf,
do_encl_op_put_to_addr,
do_encl_op_get_from_addr,
do_encl_op_nop,
do_encl_eaccept,
do_encl_emodpe,
do_encl_init_tcs_page,
};
struct encl_op_header *op = (struct encl_op_header *)rdi;
if (op->type < ENCL_OP_MAX)
(*encl_op_array[op->type])(op);
struct encl_op_header *header = (struct encl_op_header *)rdi;
encl_op_t op;
if (header->type >= ENCL_OP_MAX)
return;
/*
* The enclave base address needs to be added, as this call site
* *cannot be* made rip-relative by the compiler, or fixed up by
* any other possible means.
*/
op = ((uint64_t)&__encl_base) + encl_op_array[header->type];
(*op)(header);
}
......@@ -10,6 +10,7 @@ PHDRS
SECTIONS
{
. = 0;
__encl_base = .;
.tcs : {
*(.tcs*)
} : tcs
......@@ -23,6 +24,7 @@ SECTIONS
} : text
.data : {
*(.data.encl_buffer)
*(.data*)
} : data
......@@ -31,11 +33,9 @@ SECTIONS
*(.note*)
*(.debug*)
*(.eh_frame*)
*(.dyn*)
*(.gnu.hash)
}
}
ASSERT(!DEFINED(.altinstructions), "ALTERNATIVES are not supported in enclaves")
ASSERT(!DEFINED(.altinstr_replacement), "ALTERNATIVES are not supported in enclaves")
ASSERT(!DEFINED(.discard.retpoline_safe), "RETPOLINE ALTERNATIVES are not supported in enclaves")
ASSERT(!DEFINED(.discard.nospec), "RETPOLINE ALTERNATIVES are not supported in enclaves")
ASSERT(!DEFINED(.got.plt), "Libcalls are not supported in enclaves")
ASSERT(!DEFINED(_GLOBAL_OFFSET_TABLE_), "Libcalls through GOT are not supported in enclaves")
......@@ -42,9 +42,12 @@
encl_entry:
# RBX contains the base address for TCS, which is the first address
# inside the enclave for TCS #1 and one page into the enclave for
# TCS #2. By adding the value of encl_stack to it, we get
# the absolute address for the stack.
lea (encl_stack)(%rbx), %rax
# TCS #2. First make it relative by substracting __encl_base and
# then add the address of encl_stack to get the address for the stack.
lea __encl_base(%rip), %rax
sub %rax, %rbx
lea encl_stack(%rip), %rax
add %rbx, %rax
jmp encl_entry_core
encl_dyn_entry:
# Entry point for dynamically created TCS page expected to follow
......@@ -55,25 +58,12 @@ encl_entry_core:
push %rax
push %rcx # push the address after EENTER
push %rbx # push the enclave base address
# NOTE: as the selftest enclave is *not* intended for production,
# simplify the code by not initializing ABI registers on entry or
# cleansing caller-save registers on exit.
call encl_body
pop %rbx # pop the enclave base address
/* Clear volatile GPRs, except RAX (EEXIT function). */
xor %rcx, %rcx
xor %rdx, %rdx
xor %rdi, %rdi
xor %rsi, %rsi
xor %r8, %r8
xor %r9, %r9
xor %r10, %r10
xor %r11, %r11
# Reset status flags.
add %rdx, %rdx # OF = SF = AF = CF = 0; ZF = PF = 1
# Prepare EEXIT target by popping the address of the instruction after
# EENTER to RBX.
pop %rbx
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment