From patchwork Tue Mar 22 07:43:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jarkko Sakkinen X-Patchwork-Id: 553825 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1143AC433F5 for ; Tue, 22 Mar 2022 07:45:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229506AbiCVHqk (ORCPT ); Tue, 22 Mar 2022 03:46:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46906 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229651AbiCVHq1 (ORCPT ); Tue, 22 Mar 2022 03:46:27 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 54DD138BD9; Tue, 22 Mar 2022 00:42:23 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id B2370B81C16; Tue, 22 Mar 2022 07:42:21 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0B408C340EC; Tue, 22 Mar 2022 07:42:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1647934940; bh=uh1ULGAkBHUBMe2X6Hg0BdqpJIOUvOjHgP7tYdHOhP4=; h=From:To:Cc:Subject:Date:From; b=B7NaCOboxskKEqk973igY3cVlcuqHu2ccpPyYd4wlVvNeoEXeJx3HFP6Ie3c6esvu C5KFSYAH3sWHhbquYE+rbbjkRUkNwkmmaNKGatW74jkK2k0hmnDF32Q6Bl4NFD+vDV mGigJrNMN7L6f12oFwsUm9IQ6MWoWeeo46zkmq7UMgQI4kwT6JuFkDbDCKvdCWhT+V OTjZuSN2XGIKq1ejXKZWP5RC9eV5UmmNxm0nvvLULUHk8doST+0S9cv0bk96fuhjO1 4n9+NZVxXy60itTCX8A8UP4J9Pp6GtfvPoqv9UwjIjDM2iWAQO9lvSIlTOUAdLz3n1 34tpajqlA4UjA== From: Jarkko Sakkinen To: Shuah Khan Cc: Jarkko Sakkinen , Reinette Chatre , Dave Hansen , Shuah Khan , 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 1/2] selftests/sgx: Use rip relative addressing for encl_stack Date: Tue, 22 Mar 2022 09:43:11 +0200 Message-Id: <20220322074313.7444-1-jarkko@kernel.org> X-Mailer: git-send-email 2.35.1 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org Simplify the test_encl_bootstrap.S flow by using rip-relative addressing. Compiler does the right thing here, and this removes dependency on where TCS entries need to be located in the binary, i.e. allows the binary layout changed freely in the future. Cc: Reinette Chatre Cc: Dave Hansen Signed-off-by: Jarkko Sakkinen --- tools/testing/selftests/sgx/test_encl_bootstrap.S | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tools/testing/selftests/sgx/test_encl_bootstrap.S b/tools/testing/selftests/sgx/test_encl_bootstrap.S index 82fb0dfcbd23..1c1b5c6c4ffe 100644 --- a/tools/testing/selftests/sgx/test_encl_bootstrap.S +++ b/tools/testing/selftests/sgx/test_encl_bootstrap.S @@ -40,11 +40,7 @@ .text 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 + lea (encl_stack)(%rip), %rax xchg %rsp, %rax push %rax From patchwork Tue Mar 22 07:43:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jarkko Sakkinen X-Patchwork-Id: 553644 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E0C0EC433FE for ; Tue, 22 Mar 2022 07:45:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229548AbiCVHqn (ORCPT ); Tue, 22 Mar 2022 03:46:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46462 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229654AbiCVHq1 (ORCPT ); Tue, 22 Mar 2022 03:46:27 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 83A0128E31; Tue, 22 Mar 2022 00:42:27 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id E3F0B61520; Tue, 22 Mar 2022 07:42:26 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id A3E91C340EC; Tue, 22 Mar 2022 07:42:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1647934946; bh=gkxma+dYkNBfdMa1USHkI+B0zztS2NuVGYqVCmPTUsw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cJVlNu5W8jIidC8dx2FP5BCuNluczQehYE7CigRcJPkltj/XOGzYUJx6R07XaLY3j VCNde99UBnZZS4KFFy8jBqr9oudGx4nrZ0Or+sVF0aLm5yohE/5O69pOJY6L2+YJzs b0fmlWaleuHF024k7sqIqVV5H/qXFrUlvxcsaUjxRCU+38PHJOKSrIV+ojYQxokYmd syvXUR5OZIDrvNYJ+eYUZS2BklX44EtVszk/DN3pt3W/joYhTDmMT9/JxxAoEisI2F KUQM14dGB52SsdBB0CiE/ybEOsiCU+5cKY91F3iVuibM2tbtxKvOOU90tZPrkiFsob /4OTK+B4r63/A== From: Jarkko Sakkinen To: Shuah Khan Cc: Jarkko Sakkinen , Reinette Chatre , Dave Hansen , Shuah Khan , 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 Message-Id: <20220322074313.7444-2-jarkko@kernel.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220322074313.7444-1-jarkko@kernel.org> References: <20220322074313.7444-1-jarkko@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.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 Cc: Dave Hansen --- 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"