From 76a20bcedacdb7861b04a60e0cc5a35753ef2790 Mon Sep 17 00:00:00 2001 From: netblue30 Date: Mon, 21 Jan 2019 09:50:43 -0500 Subject: conditional testing --- src/firejail/profile.c | 52 +++++++++++++++++++++++++++++-------------- test/profiles/cond1.profile | 1 + test/profiles/cond2.profile | 1 + test/profiles/cond3.profile | 1 + test/profiles/conditional.exp | 47 ++++++++++++++++++++++++++++++++++++++ test/profiles/profiles.sh | 3 +++ 6 files changed, 88 insertions(+), 17 deletions(-) create mode 100644 test/profiles/cond1.profile create mode 100644 test/profiles/cond2.profile create mode 100644 test/profiles/cond3.profile create mode 100755 test/profiles/conditional.exp diff --git a/src/firejail/profile.c b/src/firejail/profile.c index a6d619f38..83caef199 100644 --- a/src/firejail/profile.c +++ b/src/firejail/profile.c @@ -34,11 +34,12 @@ static int profile_find(const char *name, const char *dir, int add_ext) { int rv = 0; DIR *dp; char *pname = NULL; - if (add_ext) + if (add_ext) { if (asprintf(&pname, "%s.profile", name) == -1) errExit("asprintf"); else name = pname; + } dp = opendir (dir); if (dp != NULL) { @@ -133,40 +134,54 @@ void profile_add_ignore(const char *str) { } } +typedef struct cond_t { + const char *name; // conditional name + int (*check)(void); // true if set +} Cond; + +static int check_appimage(void) { + return arg_appimage != 0; +} + +static int check_nodbus(void) { + return arg_nodbus != 0; +} + +static int check_disable_u2f(void) { + return checkcfg(CFG_BROWSER_DISABLE_U2F) != 0; +} + +Cond conditionals[] = { + {"HAS_APPIMAGE", check_appimage}, + {"HAS_NODBUS", check_nodbus}, + {"BROWSER_DISABLE_U2F", check_disable_u2f}, + { NULL, NULL } +}; int profile_check_conditional(char *ptr, int lineno, const char *fname) { - struct cond_t { - char *name; // conditional name - size_t len; // length of name - bool value; // true if set - } conditionals[] = { - {"HAS_APPIMAGE", strlen("HAS_APPIMAGE"), arg_appimage!=0}, - {"HAS_NODBUS", strlen("HAS_NODBUS"), arg_nodbus!=0}, - {"BROWSER_DISABLE_U2F", strlen("BROWSER_DISABLE_U2F"), checkcfg(CFG_BROWSER_DISABLE_U2F)!=0}, - NULL - }, *cond = conditionals; char *tmp = ptr, *msg = NULL; if (*ptr++ != '?') return 1; + Cond *cond = conditionals; while (cond->name) { // continue if not this conditional - if (strncmp(ptr, cond->name, cond->len) != 0) { + if (strncmp(ptr, cond->name, strlen(cond->name)) != 0) { cond++; continue; } - ptr += cond->len; + ptr += strlen(cond->name); if (*ptr == ' ') ptr++; if (*ptr++ != ':') { - msg = "invalid syntax: colon must come after conditional"; + msg = "invalid conditional syntax: colon must come after conditional"; ptr = tmp; goto error; } if (*ptr == '\0') { - msg = "invalid conditional line: no profile line after conditional"; + msg = "invalid conditional syntax: no profile line after conditional"; ptr = tmp; goto error; } @@ -174,7 +189,8 @@ int profile_check_conditional(char *ptr, int lineno, const char *fname) { ptr++; // if set, continue processing statement in caller - if (cond->value) { + int value = cond->check(); + if (value) { // move ptr to start of profile line ptr = strdup(ptr); if (!ptr) @@ -184,13 +200,15 @@ int profile_check_conditional(char *ptr, int lineno, const char *fname) { // quiet or include directives if ((strncmp(ptr, "quiet", 5) == 0) || (strncmp(ptr, "include", 7) == 0)) { - msg = "invalid profile line: quiet and include not allowed in conditionals"; + msg = "invalid conditional syntax: quiet and include not allowed in conditionals"; ptr = tmp; goto error; } free(tmp); // verify syntax, exit in case of error + if (arg_debug) + printf("conditional %s, %s\n", cond->name, ptr); if (profile_check_line(ptr, lineno, fname)) profile_add(ptr); } diff --git a/test/profiles/cond1.profile b/test/profiles/cond1.profile new file mode 100644 index 000000000..207914d66 --- /dev/null +++ b/test/profiles/cond1.profile @@ -0,0 +1 @@ +?HAS_NODBUS: private diff --git a/test/profiles/cond2.profile b/test/profiles/cond2.profile new file mode 100644 index 000000000..078efe161 --- /dev/null +++ b/test/profiles/cond2.profile @@ -0,0 +1 @@ +?HAS_NODBUSprivate diff --git a/test/profiles/cond3.profile b/test/profiles/cond3.profile new file mode 100644 index 000000000..7cc9ac1e0 --- /dev/null +++ b/test/profiles/cond3.profile @@ -0,0 +1 @@ +?HAS_NODBUS diff --git a/test/profiles/conditional.exp b/test/profiles/conditional.exp new file mode 100755 index 000000000..537fb361e --- /dev/null +++ b/test/profiles/conditional.exp @@ -0,0 +1,47 @@ +#!/usr/bin/expect -f +# This file is part of Firejail project +# Copyright (C) 2014-2018 Firejail Authors +# License GPL v2 + +set timeout 10 +spawn $env(SHELL) +match_max 100000 + +send -- "firejail --debug --nodbus --profile=cond1.profile\r" +expect { + timeout {puts "TESTING ERROR 0\n";exit} + "conditional HAS_NODBUS, private" +} +expect { + timeout {puts "TESTING ERROR 1\n";exit} + "Child process initialized" +} +after 100 +send -- "exit\r" +sleep 1 + +send -- "firejail --debug --profile=cond1.profile\r" +expect { + timeout {puts "TESTING ERROR 2\n";exit} + "conditional HAS_NODBUS, private" {puts "TESTING ERROR 3\n";exit} + "Child process initialized" +} +after 100 +send -- "exit\r" +sleep 1 + +send -- "firejail --profile=cond2.profile\r" +expect { + timeout {puts "TESTING ERROR 4\n";exit} + "invalid conditional syntax" +} +after 100 + +send -- "firejail --profile=cond3.profile\r" +expect { + timeout {puts "TESTING ERROR 5\n";exit} + "invalid conditional syntax" +} +after 100 + +puts "\nall done\n" diff --git a/test/profiles/profiles.sh b/test/profiles/profiles.sh index a3d24ac0c..33729927c 100755 --- a/test/profiles/profiles.sh +++ b/test/profiles/profiles.sh @@ -6,6 +6,9 @@ export MALLOC_CHECK_=3 export MALLOC_PERTURB_=$(($RANDOM % 255 + 1)) +echo "TESTING: profile conditional (test/profiles/conditional.exp)" +./conditional.exp + echo "TESTING: profile recursivity (test/profiles/profile_recursivity.exp)" ./profile_recursivity.exp -- cgit v1.2.3-54-g00ecf