Commit 3200505d authored by Jarkko Sakkinen's avatar Jarkko Sakkinen Committed by Dave Hansen

selftests/sgx: Create a heap for the test enclave

Create a heap for the test enclave, which is allocated from /dev/null,
and left unmeasured. This is beneficial by its own because it verifies
that an enclave built from multiple choices, works properly. If LSM
hooks are added for SGX some day, a multi source enclave has higher
probability to trigger bugs on access control checks.

The immediate need comes from the need to implement page reclaim tests.
In order to trigger the page reclaimer, one can just set the size of
the heap to high enough.
Signed-off-by: default avatarJarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: default avatarReinette Chatre <reinette.chatre@intel.com>
Signed-off-by: default avatarDave Hansen <dave.hansen@linux.intel.com>
Acked-by: default avatarDave Hansen <dave.hansen@linux.intel.com>
Link: https://lkml.kernel.org/r/e070c5f23578c29608051cab879b1d276963a27a.1636997631.git.reinette.chatre@intel.com
parent 5f0ce664
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
void encl_delete(struct encl *encl) void encl_delete(struct encl *encl)
{ {
struct encl_segment *heap_seg = &encl->segment_tbl[encl->nr_segments - 1];
if (encl->encl_base) if (encl->encl_base)
munmap((void *)encl->encl_base, encl->encl_size); munmap((void *)encl->encl_base, encl->encl_size);
...@@ -30,6 +32,8 @@ void encl_delete(struct encl *encl) ...@@ -30,6 +32,8 @@ void encl_delete(struct encl *encl)
if (encl->fd) if (encl->fd)
close(encl->fd); close(encl->fd);
munmap(heap_seg->src, heap_seg->size);
if (encl->segment_tbl) if (encl->segment_tbl)
free(encl->segment_tbl); free(encl->segment_tbl);
...@@ -125,11 +129,10 @@ static bool encl_ioc_add_pages(struct encl *encl, struct encl_segment *seg) ...@@ -125,11 +129,10 @@ static bool encl_ioc_add_pages(struct encl *encl, struct encl_segment *seg)
return true; return true;
} }
bool encl_load(const char *path, struct encl *encl, unsigned long heap_size)
bool encl_load(const char *path, struct encl *encl)
{ {
const char device_path[] = "/dev/sgx_enclave"; const char device_path[] = "/dev/sgx_enclave";
struct encl_segment *seg;
Elf64_Phdr *phdr_tbl; Elf64_Phdr *phdr_tbl;
off_t src_offset; off_t src_offset;
Elf64_Ehdr *ehdr; Elf64_Ehdr *ehdr;
...@@ -181,6 +184,8 @@ bool encl_load(const char *path, struct encl *encl) ...@@ -181,6 +184,8 @@ bool encl_load(const char *path, struct encl *encl)
ehdr = encl->bin; ehdr = encl->bin;
phdr_tbl = encl->bin + ehdr->e_phoff; phdr_tbl = encl->bin + ehdr->e_phoff;
encl->nr_segments = 1; /* one for the heap */
for (i = 0; i < ehdr->e_phnum; i++) { for (i = 0; i < ehdr->e_phnum; i++) {
Elf64_Phdr *phdr = &phdr_tbl[i]; Elf64_Phdr *phdr = &phdr_tbl[i];
...@@ -196,7 +201,6 @@ bool encl_load(const char *path, struct encl *encl) ...@@ -196,7 +201,6 @@ bool encl_load(const char *path, struct encl *encl)
for (i = 0, j = 0; i < ehdr->e_phnum; i++) { for (i = 0, j = 0; i < ehdr->e_phnum; i++) {
Elf64_Phdr *phdr = &phdr_tbl[i]; Elf64_Phdr *phdr = &phdr_tbl[i];
unsigned int flags = phdr->p_flags; unsigned int flags = phdr->p_flags;
struct encl_segment *seg;
if (phdr->p_type != PT_LOAD) if (phdr->p_type != PT_LOAD)
continue; continue;
...@@ -238,10 +242,21 @@ bool encl_load(const char *path, struct encl *encl) ...@@ -238,10 +242,21 @@ bool encl_load(const char *path, struct encl *encl)
j++; j++;
} }
assert(j == encl->nr_segments); assert(j == encl->nr_segments - 1);
seg = &encl->segment_tbl[j];
seg->offset = encl->segment_tbl[j - 1].offset + encl->segment_tbl[j - 1].size;
seg->size = heap_size;
seg->src = mmap(NULL, heap_size, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
seg->prot = PROT_READ | PROT_WRITE;
seg->flags = (SGX_PAGE_TYPE_REG << 8) | seg->prot;
seg->measure = false;
if (seg->src == MAP_FAILED)
goto err;
encl->src_size = encl->segment_tbl[j - 1].offset + encl->src_size = encl->segment_tbl[j].offset + encl->segment_tbl[j].size;
encl->segment_tbl[j - 1].size;
for (encl->encl_size = 4096; encl->encl_size < encl->src_size; ) for (encl->encl_size = 4096; encl->encl_size < encl->src_size; )
encl->encl_size <<= 1; encl->encl_size <<= 1;
......
...@@ -122,7 +122,7 @@ FIXTURE_SETUP(enclave) ...@@ -122,7 +122,7 @@ FIXTURE_SETUP(enclave)
unsigned int i; unsigned int i;
void *addr; void *addr;
if (!encl_load("test_encl.elf", &self->encl)) { if (!encl_load("test_encl.elf", &self->encl, ENCL_HEAP_SIZE_DEFAULT)) {
encl_delete(&self->encl); encl_delete(&self->encl);
ksft_exit_skip("cannot load enclaves\n"); ksft_exit_skip("cannot load enclaves\n");
} }
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
#ifndef MAIN_H #ifndef MAIN_H
#define MAIN_H #define MAIN_H
#define ENCL_HEAP_SIZE_DEFAULT 4096
struct encl_segment { struct encl_segment {
void *src; void *src;
off_t offset; off_t offset;
...@@ -33,7 +35,7 @@ extern unsigned char sign_key[]; ...@@ -33,7 +35,7 @@ extern unsigned char sign_key[];
extern unsigned char sign_key_end[]; extern unsigned char sign_key_end[];
void encl_delete(struct encl *ctx); void encl_delete(struct encl *ctx);
bool encl_load(const char *path, struct encl *encl); bool encl_load(const char *path, struct encl *encl, unsigned long heap_size);
bool encl_measure(struct encl *encl); bool encl_measure(struct encl *encl);
bool encl_build(struct encl *encl); bool encl_build(struct encl *encl);
......
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