Skip to content

Commit 2e9c69e

Browse files
committed
fixup! [LibOS] Test-cases for SPLRB
Signed-off-by: g2flyer <michael.steiner@intel.com>
1 parent 7c2f305 commit 2e9c69e

File tree

10 files changed

+195
-0
lines changed

10 files changed

+195
-0
lines changed

libos/test/regression/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ tests = {
8484
'c_args': '-fopenmp',
8585
'link_args': '-fopenmp',
8686
},
87+
'pf_rollback': {},
8788
'pipe': {},
8889
'pipe_nonblocking': {},
8990
'pipe_ocloexec': {},
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/* SPDX-License-Identifier: LGPL-3.0-or-later */
2+
/* Copyright (C) 2024 Intel Corporation
3+
* Paweł Marczewski <pawel@invisiblethingslab.com>
4+
* Michael Steiner <michael.steiner@intel.com>
5+
*/
6+
7+
/*
8+
* Tests for rollback protection of protected (encrypted) files
9+
*/
10+
11+
#include <assert.h>
12+
#include <err.h>
13+
#include <errno.h>
14+
#include <stdio.h>
15+
#include <stdlib.h>
16+
#include <string.h>
17+
18+
#include "common.h"
19+
#include "rw_file.h"
20+
21+
static const char message1[] = "first message\n";
22+
static const size_t message1_len = sizeof(message1) - 1;
23+
24+
static const char message2[] = "second message\n";
25+
static const size_t message2_len = sizeof(message2) - 1;
26+
27+
static_assert(sizeof(message1) != sizeof(message2), "the messages should have different lengths");
28+
29+
/* TODO: eventually remove below copy/paste/extract heap
30+
static int create_file(const char* path, const char* str, size_t len) {
31+
int fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0600);
32+
if (fd < 0)
33+
err(1, "open %s", path);
34+
35+
ssize_t n = posix_fd_write(fd, str, len);
36+
if (n < 0)
37+
errx(1, "posix_fd_write %s", path);
38+
if ((size_t)n != len)
39+
errx(1, "written less bytes than expected into %s", path);
40+
41+
if (rename(path, path) != 0)
42+
err(1, "rename");
43+
44+
if (unlink(path) != 0)
45+
err(1, "unlink %s", path);
46+
47+
if (close(fd) != 0)
48+
err(1, "close %s", path);
49+
50+
}
51+
*/
52+
53+
/* dummy functions which are gdb break-point targets */
54+
static void save_file() {}
55+
static void reset_file() {}
56+
static void delete_file() {}
57+
static void delete_second_file() {}
58+
59+
static void test_test(const char* dir) {
60+
save_file();
61+
reset_file();
62+
delete_file();
63+
delete_second_file();
64+
}
65+
66+
int main(int argc, char* argv[]) {
67+
setbuf(stdout, NULL);
68+
setbuf(stderr, NULL);
69+
70+
if (argc != 2)
71+
errx(1, "Usage: %s <dir>", argv[0]);
72+
73+
const char* dir = argv[1];
74+
75+
test_test(dir);
76+
printf("TEST OK\n");
77+
return 0;
78+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
set breakpoint pending on
2+
set pagination off
3+
set backtrace past-main on
4+
5+
# We want to check what happens in the child process after fork()
6+
set follow-fork-mode child
7+
8+
# Cannot detach after fork because of some bug in SGX version of GDB (GDB would segfault)
9+
set detach-on-fork off
10+
11+
break save_file
12+
commands
13+
python print(f"BREAK: {gdb.selected_frame().older().name()} in {gdb.selected_frame().name()}"),
14+
15+
# TODO: save file
16+
# shell echo "WRITING NEW CONTENT IN FORK_AND_ACCESS_FILE_TESTFILE" > fork_and_access_file_testfile
17+
18+
continue
19+
end
20+
21+
break reset_file
22+
commands
23+
python print(f"BREAK: {gdb.selected_frame().older().name()} in {gdb.selected_frame().name()}"),
24+
25+
# TODO: reset file
26+
# shell echo "WRITING NEW CONTENT IN FORK_AND_ACCESS_FILE_TESTFILE" > fork_and_access_file_testfile
27+
28+
continue
29+
end
30+
31+
break delete_file
32+
commands
33+
python print(f"BREAK: {gdb.selected_frame().older().name()} in {gdb.selected_frame().name()}"),
34+
35+
# TODO: delete file
36+
# shell echo "WRITING NEW CONTENT IN FORK_AND_ACCESS_FILE_TESTFILE" > fork_and_access_file_testfile
37+
38+
continue
39+
end
40+
41+
break delete_second_file
42+
commands
43+
python print(f"BREAK: {gdb.selected_frame().older().name()} in {gdb.selected_frame().name()}"),
44+
45+
# TODO: delete second file
46+
# shell echo "WRITING NEW CONTENT IN FORK_AND_ACCESS_FILE_TESTFILE" > fork_and_access_file_testfile
47+
48+
continue
49+
end
50+
51+
break die_or_inf_loop
52+
commands
53+
echo EXITING GDB WITH A GRAMINE ERROR\n
54+
quit
55+
end
56+
57+
break exit
58+
commands
59+
echo EXITING GDB WITHOUT A GRAMINE ERROR\n
60+
quit
61+
end
62+
63+
run
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
loader.entrypoint = "file:{{ gramine.libos }}"
2+
libos.entrypoint = "{{ entrypoint }}"
3+
4+
loader.env.LD_LIBRARY_PATH = "/lib:{{ arch_libdir }}:/usr/{{ arch_libdir }}"
5+
loader.insecure__use_cmdline_argv = true
6+
7+
fs.mounts = [
8+
{ path = "/lib", uri = "file:{{ gramine.runtimedir(libc) }}" },
9+
{ path = "/{{ entrypoint }}", uri = "file:{{ binary_dir }}/{{ entrypoint }}" },
10+
{ path = "/bin", uri = "file:/bin" },
11+
12+
{ type = "encrypted", protection_mode = "strict", path = "/tmp_enc/pm_strict", uri = "file:tmp_enc", key_name = "my_custom_key" },
13+
{ type = "encrypted", protection_mode = "strict", path = "/tmp_enc/pm_non_strict", uri = "file:tmp_enc", key_name = "my_custom_key" },
14+
{ type = "encrypted", protection_mode = "strict", path = "/tmp_enc/pm_none", uri = "file:tmp_enc", key_name = "my_custom_key" },
15+
]
16+
17+
sgx.max_threads = {{ '1' if env.get('EDMM', '0') == '1' else '16' }}
18+
sgx.debug = true
19+
sgx.edmm_enable = {{ 'true' if env.get('EDMM', '0') == '1' else 'false' }}
20+
21+
22+
sgx.trusted_files = [
23+
"file:{{ gramine.libos }}",
24+
"file:{{ gramine.runtimedir(libc) }}/",
25+
"file:{{ binary_dir }}/{{ entrypoint }}",
26+
]
27+
28+
# See the `keys.c` test.
29+
fs.insecure__keys.default = "ffeeddccbbaa99887766554433221100"
30+
fs.insecure__keys.my_custom_key = "00112233445566778899aabbccddeeff"

libos/test/regression/test_libos.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1385,6 +1385,27 @@ def test_020_gdb_fork_and_access_file_bug(self):
13851385
with open('fork_and_access_file_testfile', 'w') as f:
13861386
f.write('fork_and_access_file_testfile')
13871387

1388+
def test_030_gdb_pf_rollback(self):
1389+
# To run this test manually, use:
1390+
# GDB=1 GDB_SCRIPT=pf_rollback.gdb gramine-[sgx|direct] pf_rollback
1391+
#
1392+
# This test checks rollback protection.
1393+
try:
1394+
stdout, _ = self.run_gdb(['pf_rollback', '/tmp_enc/pm_strict'], 'pf_rollback.gdb')
1395+
# TODO (MST): This test is not yet implemented.
1396+
# - loop for /tmp_enc/pm_strict, /tmp_enc/pm_non_strict, /tmp_enc/pm_none
1397+
# - define expected sequence for each test
1398+
self.assertIn('BREAK: test_test in save_file', stdout)
1399+
self.assertIn('BREAK: test_test in reset_file', stdout)
1400+
self.assertIn('BREAK: test_test in delete_file', stdout)
1401+
self.assertIn('BREAK: test_test in delete_second_file', stdout)
1402+
self.assertIn('EXITING GDB WITHOUT A GRAMINE ERROR', stdout)
1403+
self.assertNotIn('EXITING GDB WITH A GRAMINE ERROR', stdout)
1404+
finally:
1405+
# restore the trusted file contents (modified by the GDB script in this test)
1406+
with open('fork_and_access_file_testfile', 'w') as f:
1407+
f.write('fork_and_access_file_testfile')
1408+
13881409
class TC_80_Socket(RegressionTestCase):
13891410
def test_000_getsockopt(self):
13901411
stdout, _ = self.run_binary(['getsockopt'])

libos/test/regression/tests.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ manifests = [
8383
"munmap",
8484
"open_opath",
8585
"openmp",
86+
"pf_rollback",
8687
"pipe",
8788
"pipe_nonblocking",
8889
"pipe_ocloexec",

libos/test/regression/tests_musl.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ manifests = [
8585
"munmap",
8686
"open_opath",
8787
"openmp",
88+
"pf_rollback",
8889
"pipe",
8990
"pipe_nonblocking",
9091
"pipe_ocloexec",

libos/test/regression/tmp_enc/pm_non_strict/.gitkeep

Whitespace-only changes.

libos/test/regression/tmp_enc/pm_none/.gitkeep

Whitespace-only changes.

libos/test/regression/tmp_enc/pm_strict/.gitkeep

Whitespace-only changes.

0 commit comments

Comments
 (0)