From: Jarkko Sakkinen <jarkko@kernel.org>
To: Shuah Khan <skhan@linuxfoundation.org>
Cc: Jarkko Sakkinen <jarkko@kernel.org>,
Reinette Chatre <reinette.chatre@intel.com>,
Dave Hansen <dave.hansen@linux.intel.com>,
Shuah Khan <shuah@kernel.org>,
linux-sgx@vger.kernel.org (open list:INTEL SGX),
linux-kselftest@vger.kernel.org (open list:KERNEL SELFTEST
FRAMEWORK), linux-kernel@vger.kernel.org (open list)
Subject: [PATCH v2 2/2] selftests/sgx: Make TCS table relocatable
Date: Tue, 22 Mar 2022 09:43:12 +0200 [thread overview]
Message-ID: <20220322074313.7444-2-jarkko@kernel.org> (raw)
In-Reply-To: <20220322074313.7444-1-jarkko@kernel.org>
Add a PT_NOTE section with n_namesz containg "TCS" and n_descz containing
32-bit offset to the TCS table inside the enclave. This allows to place the
TCS segment freely, and thereby make the kselftest binary layout way more
robust.
Cc: Reinette Chatre <reinette.chatre@intel.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
---
v2:
* Add RIP relative addressing fix for bootstrap as prepending patch, as
this depends on it.
* Moved TCS section as the last so that it is easy to add new TCS's,
e.g dynamically with EAUG + EMODT, behind it.
---
tools/testing/selftests/sgx/load.c | 56 ++++++++++++++-----
tools/testing/selftests/sgx/main.c | 37 +++---------
tools/testing/selftests/sgx/main.h | 2 +
tools/testing/selftests/sgx/test_encl.lds | 17 ++++--
.../selftests/sgx/test_encl_bootstrap.S | 7 +++
5 files changed, 72 insertions(+), 47 deletions(-)
diff --git a/tools/testing/selftests/sgx/load.c b/tools/testing/selftests/sgx/load.c
index 006b464c8fc9..214b9da631bd 100644
--- a/tools/testing/selftests/sgx/load.c
+++ b/tools/testing/selftests/sgx/load.c
@@ -19,6 +19,9 @@
#include "defines.h"
#include "main.h"
+const char *TCS_NOTE_NAME = "TCS";
+const unsigned long TCS_NOTE_LEN = 4;
+
void encl_delete(struct encl *encl)
{
struct encl_segment *heap_seg;
@@ -187,11 +190,31 @@ bool encl_load(const char *path, struct encl *encl, unsigned long heap_size)
encl->nr_segments = 1; /* one for the heap */
+ /* Count the loadable segments and discover the TCS array. */
for (i = 0; i < ehdr->e_phnum; i++) {
Elf64_Phdr *phdr = &phdr_tbl[i];
+ Elf64_Nhdr *note;
+ char *note_name;
- if (phdr->p_type == PT_LOAD)
+ switch (phdr->p_type) {
+ case PT_LOAD:
encl->nr_segments++;
+ break;
+
+ case PT_NOTE:
+ note = encl->bin + (phdr->p_offset & PAGE_MASK);
+ note_name = &((char *)note)[sizeof(*note)];
+
+ if (note->n_namesz == TCS_NOTE_LEN &&
+ !strncmp(note_name, TCS_NOTE_NAME, TCS_NOTE_LEN)) {
+ /* 32-bit address. */
+ encl->tcs = (struct sgx_tcs *)(unsigned long)(note->n_descsz);
+ }
+ break;
+
+ default:
+ break;
+ }
}
encl->segment_tbl = calloc(encl->nr_segments,
@@ -215,31 +238,36 @@ bool encl_load(const char *path, struct encl *encl, unsigned long heap_size)
goto err;
}
- if (j == 0 && flags != (PF_R | PF_W)) {
- fprintf(stderr,
- "TCS has invalid segment flags 0x%02x.\n",
- phdr->p_flags);
- goto err;
- }
-
if (j == 0) {
src_offset = phdr->p_offset & PAGE_MASK;
encl->src = encl->bin + src_offset;
+ }
+
+ seg->offset = (phdr->p_offset & PAGE_MASK) - src_offset;
+ seg->size = (phdr->p_filesz + PAGE_SIZE - 1) & PAGE_MASK;
+ seg->src = encl->src + seg->offset;
+ seg->measure = true;
+
+ if (seg->offset == (unsigned long)encl->tcs) {
+ if (flags != (PF_R | PF_W)) {
+ fprintf(stderr,
+ "TCS has invalid segment flags 0x%02x.\n",
+ phdr->p_flags);
+ goto err;
+ }
seg->prot = PROT_READ | PROT_WRITE;
seg->flags = SGX_PAGE_TYPE_TCS << 8;
} else {
+ if ((flags & (PF_R | PF_W | PF_X)) == (PF_R | PF_W))
+ encl->data_offset = seg->offset;
+
seg->prot = (phdr->p_flags & PF_R) ? PROT_READ : 0;
seg->prot |= (phdr->p_flags & PF_W) ? PROT_WRITE : 0;
seg->prot |= (phdr->p_flags & PF_X) ? PROT_EXEC : 0;
seg->flags = (SGX_PAGE_TYPE_REG << 8) | seg->prot;
}
- seg->offset = (phdr->p_offset & PAGE_MASK) - src_offset;
- seg->size = (phdr->p_filesz + PAGE_SIZE - 1) & PAGE_MASK;
- seg->src = encl->src + seg->offset;
- seg->measure = true;
-
j++;
}
@@ -322,5 +350,7 @@ bool encl_build(struct encl *encl)
return false;
}
+ encl->tcs = (struct sgx_tcs *)((unsigned long)encl->tcs + encl->encl_base);
+
return true;
}
diff --git a/tools/testing/selftests/sgx/main.c b/tools/testing/selftests/sgx/main.c
index dd74fa42302e..b206548803b4 100644
--- a/tools/testing/selftests/sgx/main.c
+++ b/tools/testing/selftests/sgx/main.c
@@ -109,25 +109,6 @@ static Elf64_Sym *vdso_symtab_get(struct vdso_symtab *symtab, const char *name)
return NULL;
}
-/*
- * Return the offset in the enclave where the data segment can be found.
- * The first RW segment loaded is the TCS, skip that to get info on the
- * data segment.
- */
-static off_t encl_get_data_offset(struct encl *encl)
-{
- int i;
-
- for (i = 1; i < encl->nr_segments; i++) {
- struct encl_segment *seg = &encl->segment_tbl[i];
-
- if (seg->prot == (PROT_READ | PROT_WRITE))
- return seg->offset;
- }
-
- return -1;
-}
-
FIXTURE(enclave) {
struct encl encl;
struct sgx_enclave_run run;
@@ -248,7 +229,7 @@ TEST_F(enclave, unclobbered_vdso)
ASSERT_TRUE(setup_test_encl(ENCL_HEAP_SIZE_DEFAULT, &self->encl, _metadata));
memset(&self->run, 0, sizeof(self->run));
- self->run.tcs = self->encl.encl_base;
+ self->run.tcs = (__u64)self->encl.tcs;
put_op.header.type = ENCL_OP_PUT_TO_BUFFER;
put_op.value = MAGIC;
@@ -321,7 +302,7 @@ TEST_F(enclave, unclobbered_vdso_oversubscribed)
ASSERT_TRUE(setup_test_encl(total_mem, &self->encl, _metadata));
memset(&self->run, 0, sizeof(self->run));
- self->run.tcs = self->encl.encl_base;
+ self->run.tcs = (__u64)self->encl.tcs;
put_op.header.type = ENCL_OP_PUT_TO_BUFFER;
put_op.value = MAGIC;
@@ -350,7 +331,7 @@ TEST_F(enclave, clobbered_vdso)
ASSERT_TRUE(setup_test_encl(ENCL_HEAP_SIZE_DEFAULT, &self->encl, _metadata));
memset(&self->run, 0, sizeof(self->run));
- self->run.tcs = self->encl.encl_base;
+ self->run.tcs = (__u64)self->encl.tcs;
put_op.header.type = ENCL_OP_PUT_TO_BUFFER;
put_op.value = MAGIC;
@@ -386,7 +367,7 @@ TEST_F(enclave, clobbered_vdso_and_user_function)
ASSERT_TRUE(setup_test_encl(ENCL_HEAP_SIZE_DEFAULT, &self->encl, _metadata));
memset(&self->run, 0, sizeof(self->run));
- self->run.tcs = self->encl.encl_base;
+ self->run.tcs = (__u64)self->encl.tcs;
self->run.user_handler = (__u64)test_handler;
self->run.user_data = 0xdeadbeef;
@@ -419,7 +400,7 @@ TEST_F(enclave, tcs_entry)
ASSERT_TRUE(setup_test_encl(ENCL_HEAP_SIZE_DEFAULT, &self->encl, _metadata));
memset(&self->run, 0, sizeof(self->run));
- self->run.tcs = self->encl.encl_base;
+ self->run.tcs = (__u64)self->encl.tcs;
op.type = ENCL_OP_NOP;
@@ -431,7 +412,7 @@ TEST_F(enclave, tcs_entry)
EXPECT_EQ(self->run.exception_addr, 0);
/* Move to the next TCS. */
- self->run.tcs = self->encl.encl_base + PAGE_SIZE;
+ self->run.tcs = (__u64)self->encl.tcs + PAGE_SIZE;
EXPECT_EQ(ENCL_CALL(&op, &self->run, true), 0);
@@ -464,11 +445,9 @@ TEST_F(enclave, pte_permissions)
ASSERT_TRUE(setup_test_encl(ENCL_HEAP_SIZE_DEFAULT, &self->encl, _metadata));
memset(&self->run, 0, sizeof(self->run));
- self->run.tcs = self->encl.encl_base;
+ self->run.tcs = (__u64)self->encl.tcs;
- data_start = self->encl.encl_base +
- encl_get_data_offset(&self->encl) +
- PAGE_SIZE;
+ data_start = self->encl.encl_base + self->encl.data_offset + PAGE_SIZE;
/*
* Sanity check to ensure it is possible to write to page that will
diff --git a/tools/testing/selftests/sgx/main.h b/tools/testing/selftests/sgx/main.h
index b45c52ec7ab3..bccb263be8d9 100644
--- a/tools/testing/selftests/sgx/main.h
+++ b/tools/testing/selftests/sgx/main.h
@@ -29,6 +29,8 @@ struct encl {
struct encl_segment *segment_tbl;
struct sgx_secs secs;
struct sgx_sigstruct sigstruct;
+ struct sgx_tcs *tcs;
+ unsigned long data_offset;
};
extern unsigned char sign_key[];
diff --git a/tools/testing/selftests/sgx/test_encl.lds b/tools/testing/selftests/sgx/test_encl.lds
index a1ec64f7d91f..d76df884d8a4 100644
--- a/tools/testing/selftests/sgx/test_encl.lds
+++ b/tools/testing/selftests/sgx/test_encl.lds
@@ -2,17 +2,15 @@ OUTPUT_FORMAT(elf64-x86-64)
PHDRS
{
- tcs PT_LOAD;
text PT_LOAD;
data PT_LOAD;
+ tcs PT_LOAD;
+ note PT_NOTE;
}
SECTIONS
{
. = 0;
- .tcs : {
- *(.tcs*)
- } : tcs
. = ALIGN(4096);
.text : {
@@ -24,11 +22,20 @@ SECTIONS
.data : {
*(.data*)
+ . = ALIGN(4096);
} : data
+ .tcs : {
+ *(.tcs*)
+ } : tcs
+
+ .note : {
+ *(.note.tcs*)
+ } : note
+
/DISCARD/ : {
*(.comment*)
- *(.note*)
+ *(.note.gnu.*)
*(.debug*)
*(.eh_frame*)
}
diff --git a/tools/testing/selftests/sgx/test_encl_bootstrap.S b/tools/testing/selftests/sgx/test_encl_bootstrap.S
index 1c1b5c6c4ffe..912b21537532 100644
--- a/tools/testing/selftests/sgx/test_encl_bootstrap.S
+++ b/tools/testing/selftests/sgx/test_encl_bootstrap.S
@@ -10,6 +10,7 @@
.section ".tcs", "aw"
.balign 4096
+encl_tcs:
.fill 1, 8, 0 # STATE (set by CPU)
.fill 1, 8, 0 # FLAGS
.quad encl_ssa_tcs1 # OSSA
@@ -90,3 +91,9 @@ encl_stack:
.balign 4096
# Stack of TCS #2
.space 4096
+
+ .section ".note.tcs", "", @progbits
+ .long 4
+ .long encl_tcs
+ .long 0
+ .string "TCS"
--
2.35.1
next prev parent reply other threads:[~2022-03-22 7:45 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-22 7:43 [PATCH v2 1/2] selftests/sgx: Use rip relative addressing for encl_stack Jarkko Sakkinen
2022-03-22 7:43 ` Jarkko Sakkinen [this message]
2022-03-28 21:49 ` Reinette Chatre
2022-03-30 14:54 ` Jarkko Sakkinen
2022-03-30 14:56 ` Jarkko Sakkinen
2022-03-30 17:40 ` Reinette Chatre
[not found] ` <f68d472877b7136c32d8770603a3de38de59c322.camel@kernel.org>
2022-03-30 19:22 ` Jarkko Sakkinen
2022-03-30 20:05 ` Reinette Chatre
2022-03-30 20:40 ` Jarkko Sakkinen
2022-03-30 21:29 ` Reinette Chatre
2022-03-30 22:30 ` Jarkko Sakkinen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220322074313.7444-2-jarkko@kernel.org \
--to=jarkko@kernel.org \
--cc=dave.hansen@linux.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-sgx@vger.kernel.org \
--cc=reinette.chatre@intel.com \
--cc=shuah@kernel.org \
--cc=skhan@linuxfoundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.