diff --git a/exile.h b/exile.h index d732c76..306b4e8 100644 --- a/exile.h +++ b/exile.h @@ -245,6 +245,12 @@ struct syscall_vow_map uint64_t vowmask; }; +struct str_to_vow_map +{ + char *str; + uint64_t value; +}; + struct exile_path_policy { const char *path; @@ -644,6 +650,73 @@ static struct syscall_vow_map exile_vow_map[] = {EXILE_SYS(futex_waitv), EXILE_SYSCALL_VOW_THREAD} }; +struct str_to_vow_map str_to_vow_map[] = +{ + { "chown", EXILE_SYSCALL_VOW_CHOWN}, + { "clone", EXILE_SYSCALL_VOW_CLONE}, + { "cpath", EXILE_SYSCALL_VOW_CPATH}, + { "dpath", EXILE_SYSCALL_VOW_DPATH}, + { "exec", EXILE_SYSCALL_VOW_EXEC}, + { "fattr", EXILE_SYSCALL_VOW_FATTR}, + { "fsnotify", EXILE_SYSCALL_VOW_FSNOTIFY}, + { "id", EXILE_SYSCALL_VOW_ID}, + { "inet", EXILE_SYSCALL_VOW_INET}, + { "ioctl", EXILE_SYSCALL_VOW_IOCTL}, + { "prctl", EXILE_SYSCALL_VOW_PRCTL}, + { "proc", EXILE_SYSCALL_VOW_PROC}, + { "prot_exec", EXILE_SYSCALL_VOW_PROT_EXEC}, + { "rpath", EXILE_SYSCALL_VOW_RPATH}, + { "sched", EXILE_SYSCALL_VOW_SCHED}, + { "seccomp_install", EXILE_SYSCALL_VOW_SECCOMP_INSTALL}, + { "shm", EXILE_SYSCALL_VOW_SHM}, + { "stdio", EXILE_SYSCALL_VOW_STDIO}, + { "thread", EXILE_SYSCALL_VOW_THREAD}, + { "unix", EXILE_SYSCALL_VOW_UNIX}, + { "wpath", EXILE_SYSCALL_VOW_WPATH}, + { "error", EXILE_SYSCALL_VOW_DENY_ERROR} +}; + +/* Converts the whitespace separated vows strings to vows flags + * + * This mainly helps readability, as lots of flags ORed together is not + * very readable. + * + * If an unkown string is found, abort() is called. + */ +uint64_t exile_vows_from_str(const char *str) +{ + uint64_t result = 0; + char current[64] = { 0 }; + char *ptr = current; + const char *end = ptr + sizeof(current)-1; + do + { + while(ptr <= end && *str != '\0' && *str != ' ') + { + *ptr = *str; + ++ptr; + ++str; + } + int found = 0; + for(size_t i = 0; i < sizeof(str_to_vow_map)/sizeof(str_to_vow_map[0]); i++) + { + if(strcmp(str_to_vow_map[i].str, current) == 0) + { + result |= str_to_vow_map[i].value; + found = 1; + break; + } + } + if(!found) + { + EXILE_LOG_ERROR("No such vow: %s\n", current); + abort(); + } + memset(current, 0, sizeof(current)); + ptr = current; + } while(*str++ != '\0'); + return result; +} static int is_valid_syscall_policy(unsigned int policy) { @@ -1999,6 +2072,8 @@ int exile_vow(uint64_t promises) return ret; } + + struct exile_launch_params { struct exile_policy *policy; /* Policy to activate before jumping to func */ diff --git a/test.c b/test.c index ad58f1b..3bcb065 100644 --- a/test.c +++ b/test.c @@ -625,6 +625,18 @@ int test_launch_get() return 0; } +int test_vows_from_str() +{ + uint64_t expected = EXILE_SYSCALL_VOW_CHOWN | EXILE_SYSCALL_VOW_WPATH | EXILE_SYSCALL_VOW_INET | EXILE_SYSCALL_VOW_DENY_ERROR; + uint64_t actual = exile_vows_from_str("chown wpath inet error"); + if(expected != actual) + { + printf("Masks don't match: %lu vs %lu\n", expected, actual); + return 1; + } + return 0; +} + struct dispatcher { char *name; @@ -651,6 +663,7 @@ struct dispatcher dispatchers[] = { { "failflags", &test_fail_flags}, { "launch", &test_launch}, { "launch-get", &test_launch_get}, + { "vow_from_str", &test_vows_from_str}, }; int main(int argc, char *argv[])