lkml.org 
[lkml]   [2022]   [Apr]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH V3 29/30] selftests/sgx: Test reclaiming of untouched page
    Date
    Removing a page from an initialized enclave involves three steps:
    (1) the user requests changing the page type to PT_TRIM via the
    SGX_IOC_ENCLAVE_MODIFY_TYPE ioctl()
    (2) on success the ENCLU[EACCEPT] instruction is run from within
    the enclave to accept the page removal
    (3) the user initiates the actual removal of the page via the
    SGX_IOC_ENCLAVE_REMOVE_PAGES ioctl().

    Remove a page that has never been accessed. This means that when the
    first ioctl() requesting page removal arrives, there will be no page
    table entry, yet a valid page table entry needs to exist for the
    ENCLU[EACCEPT] function to succeed. In this test it is verified that
    a page table entry can still be installed for a page that is in the
    process of being removed.

    Suggested-by: Haitao Huang <haitao.huang@intel.com>
    Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
    ---
    Changes since V2:
    - Rename struct sgx_enclave_modt -> struct sgx_enclave_modify_type

    Changes since V1:
    - Update to support ioctl() name change (SGX_IOC_PAGE_MODT ->
    SGX_IOC_ENCLAVE_MODIFY_TYPE) and provide secinfo as parameter instead
    of just page type (Jarkko).
    - Update test to reflect page removal ioctl() and struct name change:
    SGX_IOC_PAGE_REMOVE->SGX_IOC_ENCLAVE_REMOVE_PAGES,
    struct sgx_page_remove -> struct sgx_enclave_remove_pages (Jarkko).
    - Ensure test is skipped when SGX2 not supported by kernel.

    tools/testing/selftests/sgx/main.c | 82 ++++++++++++++++++++++++++++++
    1 file changed, 82 insertions(+)

    diff --git a/tools/testing/selftests/sgx/main.c b/tools/testing/selftests/sgx/main.c
    index f9f8e3697fa6..82cc2283be03 100644
    --- a/tools/testing/selftests/sgx/main.c
    +++ b/tools/testing/selftests/sgx/main.c
    @@ -1807,4 +1807,86 @@ TEST_F(enclave, remove_added_page_invalid_access_after_eaccept)
    EXPECT_EQ(self->run.exception_addr, data_start);
    }

    +TEST_F(enclave, remove_untouched_page)
    +{
    + struct sgx_enclave_remove_pages remove_ioc;
    + struct sgx_enclave_modify_type modt_ioc;
    + struct encl_op_eaccept eaccept_op;
    + struct sgx_secinfo secinfo;
    + unsigned long data_start;
    + int ret, errno_save;
    +
    + ASSERT_TRUE(setup_test_encl(ENCL_HEAP_SIZE_DEFAULT, &self->encl, _metadata));
    +
    + /*
    + * Hardware (SGX2) and kernel support is needed for this test. Start
    + * with check that test has a chance of succeeding.
    + */
    + memset(&modt_ioc, 0, sizeof(modt_ioc));
    + ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_MODIFY_TYPE, &modt_ioc);
    +
    + if (ret == -1) {
    + if (errno == ENOTTY)
    + SKIP(return, "Kernel does not support SGX_IOC_ENCLAVE_MODIFY_TYPE ioctl()");
    + else if (errno == ENODEV)
    + SKIP(return, "System does not support SGX2");
    + }
    +
    + /*
    + * Invalid parameters were provided during sanity check,
    + * expect command to fail.
    + */
    + EXPECT_EQ(ret, -1);
    +
    + /* SGX2 is supported by kernel and hardware, test can proceed. */
    + memset(&self->run, 0, sizeof(self->run));
    + self->run.tcs = self->encl.encl_base;
    +
    + data_start = self->encl.encl_base +
    + encl_get_data_offset(&self->encl) + PAGE_SIZE;
    +
    + memset(&modt_ioc, 0, sizeof(modt_ioc));
    + memset(&secinfo, 0, sizeof(secinfo));
    +
    + secinfo.flags = SGX_PAGE_TYPE_TRIM << 8;
    + modt_ioc.offset = encl_get_data_offset(&self->encl) + PAGE_SIZE;
    + modt_ioc.length = PAGE_SIZE;
    + modt_ioc.secinfo = (unsigned long)&secinfo;
    + ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_MODIFY_TYPE, &modt_ioc);
    + errno_save = ret == -1 ? errno : 0;
    +
    + EXPECT_EQ(ret, 0);
    + EXPECT_EQ(errno_save, 0);
    + EXPECT_EQ(modt_ioc.result, 0);
    + EXPECT_EQ(modt_ioc.count, 4096);
    +
    + /*
    + * Enter enclave via TCS #1 and approve page removal by sending
    + * EACCEPT for removed page.
    + */
    +
    + eaccept_op.epc_addr = data_start;
    + eaccept_op.flags = SGX_SECINFO_TRIM | SGX_SECINFO_MODIFIED;
    + eaccept_op.ret = 0;
    + eaccept_op.header.type = ENCL_OP_EACCEPT;
    +
    + EXPECT_EQ(ENCL_CALL(&eaccept_op, &self->run, true), 0);
    + EXPECT_EEXIT(&self->run);
    + EXPECT_EQ(self->run.exception_vector, 0);
    + EXPECT_EQ(self->run.exception_error_code, 0);
    + EXPECT_EQ(self->run.exception_addr, 0);
    + EXPECT_EQ(eaccept_op.ret, 0);
    +
    + memset(&remove_ioc, 0, sizeof(remove_ioc));
    +
    + remove_ioc.offset = encl_get_data_offset(&self->encl) + PAGE_SIZE;
    + remove_ioc.length = PAGE_SIZE;
    + ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_REMOVE_PAGES, &remove_ioc);
    + errno_save = ret == -1 ? errno : 0;
    +
    + EXPECT_EQ(ret, 0);
    + EXPECT_EQ(errno_save, 0);
    + EXPECT_EQ(remove_ioc.count, 4096);
    +}
    +
    TEST_HARNESS_MAIN
    --
    2.25.1
    \
     
     \ /
      Last update: 2022-04-05 00:40    [W:5.348 / U:1.872 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site