Skip to content

Commit

Permalink
[tests] Add "execute" subtest to memory PAL test
Browse files Browse the repository at this point in the history
This increases test coverage for EDMM (SGX feature).

Co-authored-by: Vijay Dhanraj <[email protected]>
Signed-off-by: Dmitrii Kuvaiskii <[email protected]>
Signed-off-by: Vijay Dhanraj <[email protected]>
  • Loading branch information
Dmitrii Kuvaiskii and vijaydhanraj committed Jan 31, 2023
1 parent cfecde8 commit f128bc4
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 5 deletions.
50 changes: 46 additions & 4 deletions pal/regression/memory.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: LGPL-3.0-or-later */
/* Copyright (C) 2022 Intel Corporation
/* Copyright (C) 2023 Intel Corporation
* Borys Popławski <[email protected]>
* Dmitrii Kuvaiskii <[email protected]>
*/

#include <stdbool.h>
Expand All @@ -10,6 +11,9 @@
#include "pal.h"
#include "pal_regression.h"

static void (*g_mem_exec_func)(void);

static bool g_exec_failed;
static bool g_write_failed;
static bool g_read_failed;

Expand All @@ -21,25 +25,33 @@ static void fixup_context_after_read(PAL_CONTEXT* context);

#ifdef __x86_64__
void ret(void) __attribute__((visibility("internal")));
void end_of_ret(void) __attribute__((visibility("internal")));
__asm__ (
".pushsection .text\n"
".type mem_write, @function\n"
".type mem_read, @function\n"
".type ret, @function\n"
".type end_of_ret, @function\n"
"mem_write:\n"
"movb %sil, (%rdi)\n"
"ret:\n"
"ret\n"
"mem_read:\n"
"movb (%rdi), %al\n"
"ret\n"
"ret:\n"
"ret\n"
"end_of_ret:\n"
".popsection\n"
);

static bool is_pc_at_func(uintptr_t pc, void (*func)(void)) {
return pc == (uintptr_t)func;
}

static void fixup_context_after_exec(PAL_CONTEXT* context) {
pal_context_set_ip(context, (uintptr_t)ret);
}

static void fixup_context_after_write(PAL_CONTEXT* context) {
pal_context_set_ip(context, (uintptr_t)ret);
}
Expand All @@ -55,7 +67,11 @@ static void fixup_context_after_read(PAL_CONTEXT* context) {

static void memfault_handler(bool is_in_pal, uintptr_t addr, PAL_CONTEXT* context) {
uintptr_t pc = pal_context_get_ip(context);
if (is_pc_at_func(pc, (void (*)(void))mem_write)) {
if (is_pc_at_func(pc, g_mem_exec_func)) {
fixup_context_after_exec(context);
g_exec_failed = true;
return;
} else if (is_pc_at_func(pc, (void (*)(void))mem_write)) {
fixup_context_after_write(context);
g_write_failed = true;
return;
Expand Down Expand Up @@ -83,7 +99,33 @@ int main(void) {
PalSetExceptionHandler(memfault_handler, PAL_EVENT_MEMFAULT);

void* addr1 = NULL;
CHECK(memory_alloc(PAGE_SIZE * 3, PAL_PROT_READ | PAL_PROT_WRITE, &addr1));
CHECK(memory_alloc(PAGE_SIZE * 3, PAL_PROT_READ | PAL_PROT_WRITE | PAL_PROT_EXEC, &addr1));

memcpy(addr1, ret, (uintptr_t)end_of_ret - (uintptr_t)ret);
g_mem_exec_func = (void (*)(void))addr1;

g_exec_failed = false;
COMPILER_BARRIER();
g_mem_exec_func();
COMPILER_BARRIER();
if (g_exec_failed) {
log_error("exec on RWX mem at %p failed", addr1);
PalProcessExit(1);
}

CHECK(PalVirtualMemoryProtect(addr1, PAGE_SIZE * 3, PAL_PROT_READ | PAL_PROT_WRITE));

g_exec_failed = false;
COMPILER_BARRIER();
g_mem_exec_func();
COMPILER_BARRIER();
if (!g_exec_failed) {
log_error("exec on RW mem at %p unexpectedly succeeded", addr1);
PalProcessExit(1);
}

memset(addr1, 0, (uintptr_t)end_of_ret - (uintptr_t)ret);
g_mem_exec_func = NULL;

g_write_failed = false;
COMPILER_BARRIER();
Expand Down
2 changes: 1 addition & 1 deletion pal/regression/test_pal.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ def test_300_memory(self):
except subprocess.CalledProcessError as e:
self.assertEqual(e.returncode, 1)
stderr = e.stderr.decode()
self.assertRegex(stderr, r'write to R mem at 0x[0-9a-f]+ unexpectedly succeeded')
self.assertRegex(stderr, r'exec on RW mem at 0x[0-9a-f]+ unexpectedly succeeded')

def test_400_pipe(self):
_, stderr = self.run_binary(['Pipe'])
Expand Down

0 comments on commit f128bc4

Please sign in to comment.