Skip to content

Commit

Permalink
added group filter feature
Browse files Browse the repository at this point in the history
added strace tests

docs updated

man strace details added
  • Loading branch information
salsal97 committed Aug 31, 2022
1 parent 0bfd9c4 commit e6ace76
Show file tree
Hide file tree
Showing 14 changed files with 546 additions and 72 deletions.
29 changes: 18 additions & 11 deletions doc/user-getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,18 +90,25 @@ Options:
to stop execution whenever a syscall fails. Use breakpoint
conditions to control the behavior of the breakpoint.
E.g: Use syscall number as a condition in the breakpoint
--strace-filter 'SYS_name1:SYS_name2:...'
-- Specify the set of syscalls to be traced. When filters
are specified, only those syscalls specified in the filter
--strace-filter 'SYS_name1:group1:SYS_name2:...'
-- Specify the set of syscalls or groups to be traced. When filters
are specified, only those syscalls/groups specified in the filter
will be traced, in addition to failing syscalls if
specified as described above.
E.g: To trace open and mprotect syscalls, specify
--strace-filter 'SYS_open:SYS_mprotect'
--strace-exclude-filter 'SYS_name1:SYS_name2:...'
-- Specify a set of syscalls to exclude from the strace log.
All other syscalls will be logged in the strace.
E.g: To exclude open and mprotect syscalls, specify
--strace-exclude-filter 'SYS_open:SYS_mprotect'
specified as described above. Any combination of syscalls and groups
can be used. For a list of all the groups and their consituents check
out 'man strace'
E.g: To trace open and mprotect syscalls, and 'desc' group of
syscalls (file descriptor related group), specify
--strace-filter 'SYS_open:SYS_mprotect:desc'
--strace-exclude-filter 'SYS_name1:SYS_name2:group1...'
-- Specify a set of syscalls or groups to exclude from the strace log.
All other syscalls will be logged in the strace. Failing syscalls, even
if excluded, will also be logged if --strace-failing is specified. Any
combination of syscalls and groups can be used. For a list of all the
groups and their consituents check out 'man strace'
E.g: To exclude open and mprotect syscalls and the group of
file syscalls, specify
--strace-exclude-filter='SYS_open:SYS_mprotect:file'
```
You can also specify many other parameters in a configuration file, conventionally called `config.json`, you will also use this configuration file to package your application.
Expand Down
15 changes: 15 additions & 0 deletions include/myst/syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -407,4 +407,19 @@ typedef struct myst_syscall_pair

const myst_syscall_pair_t* myst_syscall_pairs(void);

#define SYSCALL_GROUP_MAX_SIZE 128

/* Stores the syscall group name, corresponding syscalls, and number of syscalls
*/
typedef struct myst_syscall_group
{
const char* name;
const size_t group_size;
const int syscalls[SYSCALL_GROUP_MAX_SIZE];
} myst_syscall_group_t;

const int* myst_syscall_group(const char* name);

size_t myst_syscall_group_size(const char* name);

#endif /* _MYST_SYSCALL_H */
11 changes: 7 additions & 4 deletions tests/strace/.gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
1
2
3
test1.txt
test2.txt
test3.txt
test4.txt
4
5
6
7
8
9
test*.txt
2 changes: 2 additions & 0 deletions tests/strace/1test.expected.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Invalid group name or syscall name 'SYS_invali' specified in --strace-filter or --strace-exclude-filter.
Aborted (core dumped)
File renamed without changes.
2 changes: 2 additions & 0 deletions tests/strace/8test.expected.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Invalid group name or syscall name 'SYS_maa' specified in --strace-filter or --strace-exclude-filter.
Aborted (core dumped)
35 changes: 32 additions & 3 deletions tests/strace/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,21 @@ endif

OPTS += --thread-stack-size=1048576

tests: all test1 test2 test3 test4
__TESTS=1 2 3 4 5 6 7 8 9
.PHONY: $(__TESTS)

tests: $(__TESTS)
echo " === passed test strace"

$(__TESTS):
$(MAKE) test$@

test1:
-$(MYST_EXEC) rootfs /bin/strace --strace-filter=SYS_invali $(OPTS) 2> test1.txt || $(RUNTEST) diff test1.txt test1.expected.txt
$(MYST_EXEC) rootfs /bin/strace --strace-filter=SYS_invali $(OPTS) 2> test1.txt || $(RUNTEST) diff test1.txt 1test.expected.txt
echo "=== test1 passed"

test2:
-$(MYST_EXEC) rootfs /bin/strace --strace-filter=SYS_mmap --strace-exclude-filter=SYS_ioctl $(OPTS) 2> test2.txt || $(RUNTEST) diff test2.txt test2.expected.txt
$(MYST_EXEC) rootfs /bin/strace --strace-filter=SYS_mmap --strace-exclude-filter=SYS_ioctl $(OPTS) 2> test2.txt || $(RUNTEST) diff test2.txt 2test.expected.txt
echo "=== test2 passed"

test3:
Expand All @@ -44,6 +50,29 @@ test4:
cat test4.txt | grep -v "SYS_close" > 3 && $(RUNTEST) diff 3 test4.txt
echo "=== test4 passed"

test5:
$(MYST_EXEC) rootfs /bin/strace --strace-filter=file $(OPTS) 2> test5.txt
cat test5.txt | grep "SYS_" > 4 && cat test5.txt | grep -E '(SYS_open|SYS_getcwd)' > 5 && $(RUNTEST) diff 4 5
echo "=== test5 passed"

test6:
$(MYST_EXEC) rootfs /bin/strace --strace-filter=file:desc:memory $(OPTS) 2> test6.txt
cat test6.txt | grep "SYS_" > 6 && cat test6.txt | grep -E '(SYS_open|SYS_read|SYS_mmap|SYS_close|SYS_mprotect|SYS_getcwd)' > 7 && $(RUNTEST) diff 6 7
echo "=== test6 passed"

test7:
$(MYST_EXEC) rootfs /bin/strace --strace-filter=file:SYS_mmap $(OPTS) 2> test7.txt
cat test7.txt | grep "SYS_" > 8 && cat test7.txt | grep -E '(SYS_open|SYS_getcwd|SYS_mmap)' > 9 && $(RUNTEST) diff 8 9
echo "=== test7 passed"

test8:
$(MYST_EXEC) rootfs /bin/strace --strace-filter=file:SYS_maa $(OPTS) 2> test8.txt || $(RUNTEST) diff test8.txt 8test.expected.txt
echo "=== test8 passed"

test9:
$(MYST_EXEC) rootfs /bin/strace --strace-filter=file --strace-exclude-filter=SYS_mmap $(OPTS) 2> test9.txt || $(RUNTEST) diff test9.txt 2test.expected.txt
echo "=== test9 passed"

myst:
$(MAKE) -C $(TOP)/tools/myst

Expand Down
2 changes: 0 additions & 2 deletions tests/strace/test1.expected.txt

This file was deleted.

31 changes: 19 additions & 12 deletions tools/myst/host/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -396,18 +396,25 @@ Options:\n\
to stop execution whenever a syscall fails. Use breakpoint \n\
conditions to control the behavior of the breakpoint.\n\
E.g: Use syscall number as a condition in the breakpoint\n\
--strace-filter 'SYS_name1:SYS_name2:...'\n\
-- Specify the set of syscalls to be traced. When filters \n\
are specified, only those syscalls specified in the filter \n\
--strace-filter 'SYS_name1:group1:SYS_name2:...'\n\
-- Specify the set of syscalls or groups to be traced. When filters \n\
are specified, only those syscalls/groups specified in the filter \n\
will be traced, in addition to failing syscalls if\n\
specified as described above.\n\
E.g: To trace open and mprotect syscalls, specify\n\
--strace-filter 'SYS_open:SYS_mprotect'\n\
--strace-exclude-filter 'SYS_name1:SYS_name2:...'\n\
-- Specify a set of syscalls to exclude from the strace log. \n\
All other syscalls will be logged in the strace. \n\
E.g: To exclude open and mprotect syscalls, specify\n\
--strace-exclude-filter 'SYS_open:SYS_mprotect'\n\
specified as described above. Any combination of syscalls and groups \n\
can be used. For a list of all the groups and their consituents check\n\
out 'man strace' \n\
E.g: To trace open and mprotect syscalls, and 'desc' group of \n\
syscalls (file descriptor related group), specify \n\
--strace-filter 'SYS_open:SYS_mprotect:desc'\n\
--strace-exclude-filter 'SYS_name1:SYS_name2:group1...'\n\
-- Specify a set of syscalls or groups to exclude from the strace log. \n\
All other syscalls will be logged in the strace. Failing syscalls, even \n\
if excluded, will also be logged if --strace-failing is specified. Any \n\
combination of syscalls and groups can be used. For a list of all the \n\
groups and their consituents check out 'man strace' \n\
E.g: To exclude open and mprotect syscalls and the group of \n\
file syscalls, specify\n\
--strace-exclude-filter='SYS_open:SYS_mprotect:file'\n\
\n"

int exec_action(int argc, const char* argv[], const char* envp[])
Expand Down Expand Up @@ -450,7 +457,7 @@ int exec_action(int argc, const char* argv[], const char* envp[])
options.strace_config.trace_syscalls = true;
}

if (myst_parse_strace_config(&argc, argv, &options.strace_config) == 0)
if (myst_strace_parse_config(&argc, argv, &options.strace_config) == 0)
{
options.strace_config.trace_syscalls = true;
}
Expand Down
31 changes: 19 additions & 12 deletions tools/myst/host/exec_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,18 +93,25 @@ Options:\n\
to stop execution whenever a syscall fails. Use breakpoint \n\
conditions to control the behavior of the breakpoint.\n\
E.g: Use syscall number as a condition in the breakpoint\n\
--strace-filter 'SYS_name1:SYS_name2:...'\n\
-- Specify the set of syscalls to be traced. When filters \n\
are specified, only those syscalls specified in the filter \n\
--strace-filter 'SYS_name1:group1:SYS_name2:...'\n\
-- Specify the set of syscalls or groups to be traced. When filters \n\
are specified, only those syscalls/groups specified in the filter \n\
will be traced, in addition to failing syscalls if\n\
specified as described above.\n\
E.g: To trace open and mprotect syscalls, specify\n\
--strace-filter 'SYS_open:SYS_mprotect'\n\
--strace-exclude-filter 'SYS_name1:SYS_name2:...'\n\
-- Specify a set of syscalls to exclude from the strace log. \n\
All other syscalls will be logged in the strace. \n\
E.g: To exclude open and mprotect syscalls, specify\n\
--strace-exclude-filter 'SYS_open:SYS_mprotect'\n\
specified as described above. Any combination of syscalls and groups \n\
can be used. For a list of all the groups and their consituents check\n\
out 'man strace' \n\
E.g: To trace open and mprotect syscalls, and 'desc' group of \n\
syscalls (file descriptor related group), specify \n\
--strace-filter 'SYS_open:SYS_mprotect:desc'\n\
--strace-exclude-filter 'SYS_name1:SYS_name2:group1...'\n\
-- Specify a set of syscalls or groups to exclude from the strace log. \n\
All other syscalls will be logged in the strace. Failing syscalls, even \n\
if excluded, will also be logged if --strace-failing is specified. Any \n\
combination of syscalls and groups can be used. For a list of all the \n\
groups and their consituents check out 'man strace' \n\
E.g: To exclude open and mprotect syscalls and the group of \n\
file syscalls, specify\n\
--strace-exclude-filter='SYS_open:SYS_mprotect:file'\n\
\n\
"

Expand Down Expand Up @@ -137,7 +144,7 @@ static void _get_options(
opts->strace_config.trace_syscalls = true;
}

if (myst_parse_strace_config(argc, argv, &opts->strace_config) == 0)
if (myst_strace_parse_config(argc, argv, &opts->strace_config) == 0)
{
opts->strace_config.trace_syscalls = true;
}
Expand Down
2 changes: 1 addition & 1 deletion tools/myst/host/package.c
Original file line number Diff line number Diff line change
Expand Up @@ -600,7 +600,7 @@ int _exec_package(
options.strace_config.trace_syscalls = true;
}

if (myst_parse_strace_config(&argc, argv, &options.strace_config) == 0)
if (myst_strace_parse_config(&argc, argv, &options.strace_config) == 0)
{
options.strace_config.trace_syscalls = true;
}
Expand Down
92 changes: 66 additions & 26 deletions tools/myst/host/strace.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,38 @@
#include <myst/strings.h>
#include <myst/syscall.h>

int myst_strace_add_syscall_to_filter(
long num,
const char* name,
myst_strace_config_t* strace_config,
bool include)
{
if (num >= 0)
{
if (num < MYST_MAX_SYSCALLS)
strace_config->trace[num] = include;
else
{
fprintf(
stderr,
"Syscall %s exceeds trace array. Fix "
"myst_syscall_config_t\n",
name);
abort();
}
}
else
{
fprintf(
stderr,
"Unknown syscall %s specified in --strace-filter or "
"--strace-exclude-filter\n",
name);
abort();
}
return 0;
}

int myst_set_strace_filter(
int num_tokens,
char** tokens,
Expand All @@ -22,36 +54,44 @@ int myst_set_strace_filter(
for (size_t i = 0; i < num_tokens; ++i)
{
const char* name = tokens[i];

/* Check if filter is for a syscall */
long num = myst_syscall_num(name);
if (num >= 0)

if (num != -ENOENT)
myst_strace_add_syscall_to_filter(
num, name, strace_config, include);
else
{
if (num < MYST_MAX_SYSCALLS)
strace_config->trace[num] = include;
else
/* Check if filter is for a group of syscalls. Eg: file, memory, etc
*/
const int* syscalls = myst_syscall_group(name);
const size_t group_size = myst_syscall_group_size(name);

/* token specified is not a syscall name or group name */
if (syscalls == NULL)
{
fprintf(
stderr,
"Syscall %s exceeds trace array. Fix "
"myst_syscall_config_t\n",
"Invalid group name or syscall name '%s' specified in "
"--strace-filter or --strace-exclude-filter.\n",
name);
abort();
}
}
else
{
fprintf(
stderr,
"Unknown syscall %s specified in --strace-filter or "
"--strace-exclude-filter \n",
name);
abort();

for (int j = 0; j < group_size; j++)
{
const char* name = myst_syscall_name((long)syscalls[j]);
myst_strace_add_syscall_to_filter(
(long)syscalls[j], name, strace_config, include);
}
}
}
strace_config->filter = 1;
return 0;
}

int myst_parse_strace_config(
int myst_strace_parse_config(
int* argc,
const char** argv,
myst_strace_config_t* strace_config)
Expand All @@ -68,20 +108,23 @@ int myst_parse_strace_config(
strace_config->filter = 1;
}

if (cli_getopt(argc, argv, "--strace-filter", &filter) == 0 && filter)
if (cli_getopt(argc, argv, "--strace-exclude-filter", &filter) == 0 &&
filter)
{
if (myst_strsplit(filter, ":", &tokens, &num_tokens) != 0)
{
fprintf(stderr, "Invalid strace-filter '%s' specified.\n", filter);
fprintf(
stderr,
"Invalid strace-exclude-filter '%s' specified.\n",
filter);
abort();
}

ret = myst_set_strace_filter(num_tokens, tokens, strace_config, 1);
ret = myst_set_strace_filter(num_tokens, tokens, strace_config, 0);
filter_flag = true;
}

if (cli_getopt(argc, argv, "--strace-exclude-filter", &filter) == 0 &&
filter)
if (cli_getopt(argc, argv, "--strace-filter", &filter) == 0 && filter)
{
if (filter_flag)
{
Expand All @@ -94,14 +137,11 @@ int myst_parse_strace_config(

if (myst_strsplit(filter, ":", &tokens, &num_tokens) != 0)
{
fprintf(
stderr,
"Invalid strace-exclude-filter '%s' specified.\n",
filter);
fprintf(stderr, "Invalid strace-filter '%s' specified.\n", filter);
abort();
}

ret = myst_set_strace_filter(num_tokens, tokens, strace_config, 0);
ret = myst_set_strace_filter(num_tokens, tokens, strace_config, 1);
}

if (tokens)
Expand Down
Loading

0 comments on commit e6ace76

Please sign in to comment.