Skip to content

Commit

Permalink
fixup! [LibOS] Test-cases for SPLRB
Browse files Browse the repository at this point in the history
Signed-off-by: g2flyer <[email protected]>
  • Loading branch information
g2flyer committed Jun 3, 2024
1 parent 7c2f305 commit 2e9c69e
Show file tree
Hide file tree
Showing 10 changed files with 195 additions and 0 deletions.
1 change: 1 addition & 0 deletions libos/test/regression/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ tests = {
'c_args': '-fopenmp',
'link_args': '-fopenmp',
},
'pf_rollback': {},
'pipe': {},
'pipe_nonblocking': {},
'pipe_ocloexec': {},
Expand Down
78 changes: 78 additions & 0 deletions libos/test/regression/pf_rollback.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/* SPDX-License-Identifier: LGPL-3.0-or-later */
/* Copyright (C) 2024 Intel Corporation
* Paweł Marczewski <[email protected]>
* Michael Steiner <[email protected]>
*/

/*
* Tests for rollback protection of protected (encrypted) files
*/

#include <assert.h>
#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "common.h"
#include "rw_file.h"

static const char message1[] = "first message\n";
static const size_t message1_len = sizeof(message1) - 1;

static const char message2[] = "second message\n";
static const size_t message2_len = sizeof(message2) - 1;

static_assert(sizeof(message1) != sizeof(message2), "the messages should have different lengths");

/* TODO: eventually remove below copy/paste/extract heap
static int create_file(const char* path, const char* str, size_t len) {
int fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0600);
if (fd < 0)
err(1, "open %s", path);
ssize_t n = posix_fd_write(fd, str, len);
if (n < 0)
errx(1, "posix_fd_write %s", path);
if ((size_t)n != len)
errx(1, "written less bytes than expected into %s", path);
if (rename(path, path) != 0)
err(1, "rename");
if (unlink(path) != 0)
err(1, "unlink %s", path);
if (close(fd) != 0)
err(1, "close %s", path);
}
*/

/* dummy functions which are gdb break-point targets */
static void save_file() {}
static void reset_file() {}
static void delete_file() {}
static void delete_second_file() {}

static void test_test(const char* dir) {
save_file();
reset_file();
delete_file();
delete_second_file();
}

int main(int argc, char* argv[]) {
setbuf(stdout, NULL);
setbuf(stderr, NULL);

if (argc != 2)
errx(1, "Usage: %s <dir>", argv[0]);

const char* dir = argv[1];

test_test(dir);
printf("TEST OK\n");
return 0;
}
63 changes: 63 additions & 0 deletions libos/test/regression/pf_rollback.gdb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
set breakpoint pending on
set pagination off
set backtrace past-main on

# We want to check what happens in the child process after fork()
set follow-fork-mode child

# Cannot detach after fork because of some bug in SGX version of GDB (GDB would segfault)
set detach-on-fork off

break save_file
commands
python print(f"BREAK: {gdb.selected_frame().older().name()} in {gdb.selected_frame().name()}"),

# TODO: save file
# shell echo "WRITING NEW CONTENT IN FORK_AND_ACCESS_FILE_TESTFILE" > fork_and_access_file_testfile

continue
end

break reset_file
commands
python print(f"BREAK: {gdb.selected_frame().older().name()} in {gdb.selected_frame().name()}"),

# TODO: reset file
# shell echo "WRITING NEW CONTENT IN FORK_AND_ACCESS_FILE_TESTFILE" > fork_and_access_file_testfile

continue
end

break delete_file
commands
python print(f"BREAK: {gdb.selected_frame().older().name()} in {gdb.selected_frame().name()}"),

# TODO: delete file
# shell echo "WRITING NEW CONTENT IN FORK_AND_ACCESS_FILE_TESTFILE" > fork_and_access_file_testfile

continue
end

break delete_second_file
commands
python print(f"BREAK: {gdb.selected_frame().older().name()} in {gdb.selected_frame().name()}"),

# TODO: delete second file
# shell echo "WRITING NEW CONTENT IN FORK_AND_ACCESS_FILE_TESTFILE" > fork_and_access_file_testfile

continue
end

break die_or_inf_loop
commands
echo EXITING GDB WITH A GRAMINE ERROR\n
quit
end

break exit
commands
echo EXITING GDB WITHOUT A GRAMINE ERROR\n
quit
end

run
30 changes: 30 additions & 0 deletions libos/test/regression/pf_rollback.manifest.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
loader.entrypoint = "file:{{ gramine.libos }}"
libos.entrypoint = "{{ entrypoint }}"

loader.env.LD_LIBRARY_PATH = "/lib:{{ arch_libdir }}:/usr/{{ arch_libdir }}"
loader.insecure__use_cmdline_argv = true

fs.mounts = [
{ path = "/lib", uri = "file:{{ gramine.runtimedir(libc) }}" },
{ path = "/{{ entrypoint }}", uri = "file:{{ binary_dir }}/{{ entrypoint }}" },
{ path = "/bin", uri = "file:/bin" },

{ type = "encrypted", protection_mode = "strict", path = "/tmp_enc/pm_strict", uri = "file:tmp_enc", key_name = "my_custom_key" },
{ type = "encrypted", protection_mode = "strict", path = "/tmp_enc/pm_non_strict", uri = "file:tmp_enc", key_name = "my_custom_key" },
{ type = "encrypted", protection_mode = "strict", path = "/tmp_enc/pm_none", uri = "file:tmp_enc", key_name = "my_custom_key" },
]

sgx.max_threads = {{ '1' if env.get('EDMM', '0') == '1' else '16' }}
sgx.debug = true
sgx.edmm_enable = {{ 'true' if env.get('EDMM', '0') == '1' else 'false' }}


sgx.trusted_files = [
"file:{{ gramine.libos }}",
"file:{{ gramine.runtimedir(libc) }}/",
"file:{{ binary_dir }}/{{ entrypoint }}",
]

# See the `keys.c` test.
fs.insecure__keys.default = "ffeeddccbbaa99887766554433221100"
fs.insecure__keys.my_custom_key = "00112233445566778899aabbccddeeff"
21 changes: 21 additions & 0 deletions libos/test/regression/test_libos.py
Original file line number Diff line number Diff line change
Expand Up @@ -1385,6 +1385,27 @@ def test_020_gdb_fork_and_access_file_bug(self):
with open('fork_and_access_file_testfile', 'w') as f:
f.write('fork_and_access_file_testfile')

def test_030_gdb_pf_rollback(self):
# To run this test manually, use:
# GDB=1 GDB_SCRIPT=pf_rollback.gdb gramine-[sgx|direct] pf_rollback
#
# This test checks rollback protection.
try:
stdout, _ = self.run_gdb(['pf_rollback', '/tmp_enc/pm_strict'], 'pf_rollback.gdb')
# TODO (MST): This test is not yet implemented.
# - loop for /tmp_enc/pm_strict, /tmp_enc/pm_non_strict, /tmp_enc/pm_none
# - define expected sequence for each test
self.assertIn('BREAK: test_test in save_file', stdout)
self.assertIn('BREAK: test_test in reset_file', stdout)
self.assertIn('BREAK: test_test in delete_file', stdout)
self.assertIn('BREAK: test_test in delete_second_file', stdout)
self.assertIn('EXITING GDB WITHOUT A GRAMINE ERROR', stdout)
self.assertNotIn('EXITING GDB WITH A GRAMINE ERROR', stdout)
finally:
# restore the trusted file contents (modified by the GDB script in this test)
with open('fork_and_access_file_testfile', 'w') as f:
f.write('fork_and_access_file_testfile')

class TC_80_Socket(RegressionTestCase):
def test_000_getsockopt(self):
stdout, _ = self.run_binary(['getsockopt'])
Expand Down
1 change: 1 addition & 0 deletions libos/test/regression/tests.toml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ manifests = [
"munmap",
"open_opath",
"openmp",
"pf_rollback",
"pipe",
"pipe_nonblocking",
"pipe_ocloexec",
Expand Down
1 change: 1 addition & 0 deletions libos/test/regression/tests_musl.toml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ manifests = [
"munmap",
"open_opath",
"openmp",
"pf_rollback",
"pipe",
"pipe_nonblocking",
"pipe_ocloexec",
Expand Down
Empty file.
Empty file.
Empty file.

0 comments on commit 2e9c69e

Please sign in to comment.