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 5, 2024
1 parent 7c2f305 commit d220ddb
Show file tree
Hide file tree
Showing 7 changed files with 226 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
81 changes: 81 additions & 0 deletions libos/test/regression/pf_rollback.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/* 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 */
#pragma GCC push_options
#pragma GCC optimize("O0")
static void adversary_save_file(const char* path) {}
static void adversary_reset_file(const char* path) {}
static void adversary_delete_file(const char* path) {}
#pragma GCC pop_options

static void test_test(const char* path1, const char* path2) {
adversary_save_file(path1);
adversary_reset_file(path1);
adversary_delete_file(path1);
adversary_delete_file(path2);
}

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

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

const char* path1 = argv[1];
const char* path2 = argv[2];

test_test(path1, path2);
printf("TEST OK\n");
return 0;
}
89 changes: 89 additions & 0 deletions libos/test/regression/pf_rollback.gdb
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
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 adversary_save_file
commands
python
# extract interesting info from context
test_function=gdb.selected_frame().older().name()
operation=gdb.selected_frame().name()
internal_path=gdb.selected_frame().read_var('path').string()
external_path=re.sub(r'/tmp_enc/pm_[^/]*/', './tmp_enc/', internal_path)
external_path_saved=external_path+"._saved_"

# execute and report result for pytest digestion
try:
import shutil
shutil.copyfile(external_path, external_path_saved)
print(f"OK: {test_function} in {operation}({internal_path})")
except:
print(f"FAIL: {test_function} in {operation}({internal_path})")
end

continue
end

break adversary_reset_file
commands
python
# extract interesting info from context
test_function=gdb.selected_frame().older().name()
operation=gdb.selected_frame().name()
internal_path=gdb.selected_frame().read_var('path').string()
external_path=re.sub(r'/tmp_enc/pm_[^/]*/', './tmp_enc/', internal_path)
external_path_saved=external_path+"._saved_"

# execute and report result for pytest digestion
try:
import shutil
shutil.move(external_path_saved, external_path)
print(f"OK: {test_function} in {operation}({internal_path})")
except:
print(f"FAIL: {test_function} in {operation}({internal_path})")
end

continue
end

break adversary_delete_file
commands
python
# extract interesting info from context
test_function=gdb.selected_frame().older().name()
operation=gdb.selected_frame().name()
internal_path=gdb.selected_frame().read_var('path').string()
external_path=re.sub(r'/tmp_enc/pm_[^/]*/', './tmp_enc/', internal_path)
external_path_saved=external_path+"._saved_"

# execute and report result for pytest digestion
try:
import pathlib
pathlib.Path.unlink(external_path)
print(f"OK: {test_function} in {operation}({internal_path})")
except:
print(f"FAIL: {test_function} in {operation}({internal_path})")
end

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 = "non-strict", path = "/tmp_enc/pm_non_strict", uri = "file:tmp_enc", key_name = "my_custom_key" },
{ type = "encrypted", protection_mode = "none", 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"
23 changes: 23 additions & 0 deletions libos/test/regression/test_libos.py
Original file line number Diff line number Diff line change
Expand Up @@ -1385,6 +1385,29 @@ 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 <file1> <file2>
#
# This test checks rollback protection.
try:
file1='/tmp_enc/pm_strict/file1'
file2='/tmp_enc/pm_strict/file2'
stdout, _ = self.run_gdb(['pf_rollback', file1, file2], '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('OK: test_test in adversary_save_file', stdout)
self.assertIn('OK: test_test in adversary_reset_file', stdout)
self.assertIn(f'OK: test_test in adversary_delete_file({file1})', stdout)
self.assertIn(f'OK: test_test in adversary_delete_file({file2})', 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

0 comments on commit d220ddb

Please sign in to comment.