linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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


  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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).