selftests/sgx: Refine the test enclave to have storage

Extend the enclave to have two operations: ENCL_OP_PUT and ENCL_OP_GET.
ENCL_OP_PUT stores value inside the enclave address space and
ENCL_OP_GET reads it. The internal buffer can be later extended to be
variable size, and allow reclaimer tests.

Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
This commit is contained in:
Jarkko Sakkinen 2021-06-10 11:30:21 +03:00 committed by Shuah Khan
parent b334fb6fa7
commit 22118ce17e
4 changed files with 74 additions and 15 deletions

View file

@ -18,4 +18,14 @@
#include "../../../../arch/x86/include/asm/enclu.h"
#include "../../../../arch/x86/include/uapi/asm/sgx.h"
enum encl_op_type {
ENCL_OP_PUT,
ENCL_OP_GET,
};
struct encl_op {
uint64_t type;
uint64_t buffer;
};
#endif /* DEFINES_H */

View file

@ -193,14 +193,14 @@ FIXTURE_TEARDOWN(enclave)
encl_delete(&self->encl);
}
#define ENCL_CALL(in, out, run, clobbered) \
#define ENCL_CALL(op, run, clobbered) \
({ \
int ret; \
if ((clobbered)) \
ret = vdso_sgx_enter_enclave((unsigned long)(in), (unsigned long)(out), 0, \
ret = vdso_sgx_enter_enclave((unsigned long)(op), 0, 0, \
EENTER, 0, 0, (run)); \
else \
ret = sgx_enter_enclave((void *)(in), (void *)(out), 0, EENTER, NULL, NULL, \
ret = sgx_enter_enclave((void *)(op), NULL, 0, EENTER, NULL, NULL, \
(run)); \
ret; \
})
@ -215,22 +215,44 @@ FIXTURE_TEARDOWN(enclave)
TEST_F(enclave, unclobbered_vdso)
{
uint64_t result = 0;
struct encl_op op;
EXPECT_EQ(ENCL_CALL(&MAGIC, &result, &self->run, false), 0);
op.type = ENCL_OP_PUT;
op.buffer = MAGIC;
EXPECT_EQ(result, MAGIC);
EXPECT_EQ(ENCL_CALL(&op, &self->run, false), 0);
EXPECT_EEXIT(&self->run);
EXPECT_EQ(self->run.user_data, 0);
op.type = ENCL_OP_GET;
op.buffer = 0;
EXPECT_EQ(ENCL_CALL(&op, &self->run, false), 0);
EXPECT_EQ(op.buffer, MAGIC);
EXPECT_EEXIT(&self->run);
EXPECT_EQ(self->run.user_data, 0);
}
TEST_F(enclave, clobbered_vdso)
{
uint64_t result = 0;
struct encl_op op;
EXPECT_EQ(ENCL_CALL(&MAGIC, &result, &self->run, true), 0);
op.type = ENCL_OP_PUT;
op.buffer = MAGIC;
EXPECT_EQ(result, MAGIC);
EXPECT_EQ(ENCL_CALL(&op, &self->run, true), 0);
EXPECT_EEXIT(&self->run);
EXPECT_EQ(self->run.user_data, 0);
op.type = ENCL_OP_GET;
op.buffer = 0;
EXPECT_EQ(ENCL_CALL(&op, &self->run, true), 0);
EXPECT_EQ(op.buffer, MAGIC);
EXPECT_EEXIT(&self->run);
EXPECT_EQ(self->run.user_data, 0);
}
@ -245,14 +267,25 @@ static int test_handler(long rdi, long rsi, long rdx, long ursp, long r8, long r
TEST_F(enclave, clobbered_vdso_and_user_function)
{
uint64_t result = 0;
struct encl_op op;
self->run.user_handler = (__u64)test_handler;
self->run.user_data = 0xdeadbeef;
EXPECT_EQ(ENCL_CALL(&MAGIC, &result, &self->run, true), 0);
op.type = ENCL_OP_PUT;
op.buffer = MAGIC;
EXPECT_EQ(result, MAGIC);
EXPECT_EQ(ENCL_CALL(&op, &self->run, true), 0);
EXPECT_EEXIT(&self->run);
EXPECT_EQ(self->run.user_data, 0);
op.type = ENCL_OP_GET;
op.buffer = 0;
EXPECT_EQ(ENCL_CALL(&op, &self->run, true), 0);
EXPECT_EQ(op.buffer, MAGIC);
EXPECT_EEXIT(&self->run);
EXPECT_EQ(self->run.user_data, 0);
}

View file

@ -4,6 +4,8 @@
#include <stddef.h>
#include "defines.h"
static uint8_t encl_buffer[8192] = { 1 };
static void *memcpy(void *dest, const void *src, size_t n)
{
size_t i;
@ -14,7 +16,20 @@ static void *memcpy(void *dest, const void *src, size_t n)
return dest;
}
void encl_body(void *rdi, void *rsi)
void encl_body(void *rdi, void *rsi)
{
memcpy(rsi, rdi, 8);
struct encl_op *op = (struct encl_op *)rdi;
switch (op->type) {
case ENCL_OP_PUT:
memcpy(&encl_buffer[0], &op->buffer, 8);
break;
case ENCL_OP_GET:
memcpy(&op->buffer, &encl_buffer[0], 8);
break;
default:
break;
}
}

View file

@ -18,9 +18,10 @@ SECTIONS
.text : {
*(.text*)
*(.rodata*)
FILL(0xDEADBEEF);
. = ALIGN(4096);
} : text
. = ALIGN(4096);
.data : {
*(.data*)
} : data