selftests/sgx: Create a heap for the test enclave
authorJarkko Sakkinen <jarkko@kernel.org>
Mon, 15 Nov 2021 18:35:17 +0000 (10:35 -0800)
committerDave Hansen <dave.hansen@linux.intel.com>
Mon, 15 Nov 2021 19:34:03 +0000 (11:34 -0800)
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: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Acked-by: Dave Hansen <dave.hansen@linux.intel.com>
Link: https://lkml.kernel.org/r/e070c5f23578c29608051cab879b1d276963a27a.1636997631.git.reinette.chatre@intel.com
tools/testing/selftests/sgx/load.c
tools/testing/selftests/sgx/main.c
tools/testing/selftests/sgx/main.h

index f1be78984c501690d753971ad5e5200a3f01f657..9d4322c946e2bed95891933c1c924e532ff4a24b 100644 (file)
@@ -21,6 +21,8 @@
 
 void encl_delete(struct encl *encl)
 {
+       struct encl_segment *heap_seg = &encl->segment_tbl[encl->nr_segments - 1];
+
        if (encl->encl_base)
                munmap((void *)encl->encl_base, encl->encl_size);
 
@@ -30,6 +32,8 @@ void encl_delete(struct encl *encl)
        if (encl->fd)
                close(encl->fd);
 
+       munmap(heap_seg->src, heap_seg->size);
+
        if (encl->segment_tbl)
                free(encl->segment_tbl);
 
@@ -125,11 +129,10 @@ static bool encl_ioc_add_pages(struct encl *encl, struct encl_segment *seg)
        return true;
 }
 
-
-
-bool encl_load(const char *path, struct encl *encl)
+bool encl_load(const char *path, struct encl *encl, unsigned long heap_size)
 {
        const char device_path[] = "/dev/sgx_enclave";
+       struct encl_segment *seg;
        Elf64_Phdr *phdr_tbl;
        off_t src_offset;
        Elf64_Ehdr *ehdr;
@@ -181,6 +184,8 @@ bool encl_load(const char *path, struct encl *encl)
        ehdr = encl->bin;
        phdr_tbl = encl->bin + ehdr->e_phoff;
 
+       encl->nr_segments = 1; /* one for the heap */
+
        for (i = 0; i < ehdr->e_phnum; i++) {
                Elf64_Phdr *phdr = &phdr_tbl[i];
 
@@ -196,7 +201,6 @@ bool encl_load(const char *path, struct encl *encl)
        for (i = 0, j = 0; i < ehdr->e_phnum; i++) {
                Elf64_Phdr *phdr = &phdr_tbl[i];
                unsigned int flags = phdr->p_flags;
-               struct encl_segment *seg;
 
                if (phdr->p_type != PT_LOAD)
                        continue;
@@ -238,10 +242,21 @@ bool encl_load(const char *path, struct encl *encl)
                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->segment_tbl[j - 1].size;
+       encl->src_size = encl->segment_tbl[j].offset + encl->segment_tbl[j].size;
 
        for (encl->encl_size = 4096; encl->encl_size < encl->src_size; )
                encl->encl_size <<= 1;
index e252015e0c1544d3825b4c71d06c4f486b668694..6858a35fed20d3b8979b77004b8811c48273bbd2 100644 (file)
@@ -122,7 +122,7 @@ FIXTURE_SETUP(enclave)
        unsigned int i;
        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);
                ksft_exit_skip("cannot load enclaves\n");
        }
index aebc69e7cdc84d14a9833bd79dcc812e5380b26f..b45c52ec7ab3b5972c31c54e651b293e7c1cca5c 100644 (file)
@@ -6,6 +6,8 @@
 #ifndef MAIN_H
 #define MAIN_H
 
+#define ENCL_HEAP_SIZE_DEFAULT 4096
+
 struct encl_segment {
        void *src;
        off_t offset;
@@ -33,7 +35,7 @@ extern unsigned char sign_key[];
 extern unsigned char sign_key_end[];
 
 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_build(struct encl *encl);