From 1a7663e89a010ca48da155e632853852f5fc201f Mon Sep 17 00:00:00 2001 From: Tyler Hicks Date: Fri, 18 Mar 2016 17:28:51 -0500 Subject: [PATCH] parser: Check kernel stacking support when handling stacked transitions Check if the current kernel supports stacking. If not, ensure that named transitions (exec, change_profile, etc.) do not attempt to stack their targets. Also, set up the change_profile vector according to whether or not the kernel supports stacking. Earlier kernels expect the policy namespace to be in its own NUL-terminated vector element rather than passing the entire label (namespace and profile name) as a single string to the kernel. Signed-off-by: Tyler Hicks Acked-by: Seth Arnold --- parser/parser.h | 4 +++- parser/parser_common.c | 1 + parser/parser_main.c | 2 ++ parser/parser_misc.c | 36 +++++++++++++++++++++++++++++------- parser/parser_regex.c | 24 +++++++++++++++++++++++- parser/parser_yacc.y | 2 +- 6 files changed, 59 insertions(+), 10 deletions(-) diff --git a/parser/parser.h b/parser/parser.h index 81f211ad5..e7acda609 100644 --- a/parser/parser.h +++ b/parser/parser.h @@ -298,6 +298,7 @@ extern int kernel_supports_dbus; extern int kernel_supports_signal; extern int kernel_supports_ptrace; extern int kernel_supports_unix; +extern int kernel_supports_stacking; extern int conf_verbose; extern int conf_quiet; extern int names_only; @@ -386,7 +387,8 @@ extern char *process_var(const char *var); extern int parse_mode(const char *mode); extern int parse_X_mode(const char *X, int valid, const char *str_mode, int *mode, int fail); bool label_contains_ns(const char *label); -void parse_label(bool *stack, char **ns, char **name, const char *label); +bool parse_label(bool *_stack, char **_ns, char **_name, + const char *label, bool yyerr); extern struct cod_entry *new_entry(char *id, int mode, char *link_id); /* returns -1 if value != true or false, otherwise 0 == false, 1 == true */ diff --git a/parser/parser_common.c b/parser/parser_common.c index ab36a5315..4d5d8141e 100644 --- a/parser/parser_common.c +++ b/parser/parser_common.c @@ -73,6 +73,7 @@ int kernel_supports_dbus = 0; /* kernel supports dbus rules */ int kernel_supports_diff_encode = 0; /* kernel supports diff_encode */ int kernel_supports_signal = 0; /* kernel supports signal rules */ int kernel_supports_ptrace = 0; /* kernel supports ptrace rules */ +int kernel_supports_stacking = 0; /* kernel supports stacking */ int conf_verbose = 0; int conf_quiet = 0; int names_only = 0; diff --git a/parser/parser_main.c b/parser/parser_main.c index dbf353d28..bf3cf844c 100644 --- a/parser/parser_main.c +++ b/parser/parser_main.c @@ -638,6 +638,8 @@ static void set_supported_features(void) "policy/set_load"); kernel_supports_diff_encode = aa_features_supports(features, "policy/diff_encode"); + kernel_supports_stacking = aa_features_supports(features, + "domain/stack"); if (aa_features_supports(features, "policy/versions/v7")) kernel_abi_version = 7; diff --git a/parser/parser_misc.c b/parser/parser_misc.c index 22f6feff4..4ec04e2f2 100644 --- a/parser/parser_misc.c +++ b/parser/parser_misc.c @@ -661,8 +661,10 @@ bool label_contains_ns(const char *label) return _parse_label(&stack, &ns, &ns_len, &name, &name_len, label) == 0 && ns; } -void parse_label(bool *_stack, char **_ns, char **_name, const char *label) +bool parse_label(bool *_stack, char **_ns, char **_name, + const char *label, bool yyerr) { + const char *err = NULL; char *ns = NULL; char *name = NULL; size_t ns_len = 0; @@ -671,19 +673,28 @@ void parse_label(bool *_stack, char **_ns, char **_name, const char *label) res = _parse_label(_stack, &ns, &ns_len, &name, &name_len, label); if (res == 1) { - yyerror(_("Namespace not terminated: %s\n"), label); + err = _("Namespace not terminated: %s\n"); } else if (res == 2) { - yyerror(_("Empty namespace: %s\n"), label); + err = _("Empty namespace: %s\n"); } else if (res == 3) { - yyerror(_("Empty named transition profile name: %s\n"), label); + err = _("Empty named transition profile name: %s\n"); } else if (res != 0) { - yyerror(_("Unknown error while parsing label: %s\n"), label); + err = _("Unknown error while parsing label: %s\n"); + } + + if (err) { + if (yyerr) + yyerror(err, label); + else + fprintf(stderr, err, label); + + return false; } if (ns) { *_ns = strndup(ns, ns_len); if (!*_ns) - yyerror(_("Memory allocation error.")); + goto alloc_fail; } else { *_ns = NULL; } @@ -691,8 +702,19 @@ void parse_label(bool *_stack, char **_ns, char **_name, const char *label) *_name = strndup(name, name_len); if (!*_name) { free(*_ns); - yyerror(_("Memory allocation error.")); + goto alloc_fail; } + + return true; + +alloc_fail: + err = _("Memory allocation error."); + if (yyerr) + yyerror(err); + else + fprintf(stderr, "%s", err); + + return false; } struct cod_entry *new_entry(char *id, int mode, char *link_id) diff --git a/parser/parser_regex.c b/parser/parser_regex.c index 927007664..8cc08c602 100644 --- a/parser/parser_regex.c +++ b/parser/parser_regex.c @@ -566,6 +566,8 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry) if (entry->mode & AA_CHANGE_PROFILE) { const char *vec[3]; std::string lbuf, xbuf; + autofree char *ns = NULL; + autofree char *name = NULL; int index = 1; if ((warnflags & WARN_RULE_DOWNGRADED) && entry->audit && warn_change_profile) { @@ -585,7 +587,27 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry) /* allow change_profile for all execs */ vec[0] = "/[^/\\x00][^\\x00]*"; - vec[index++] = tbuf.c_str(); + if (!kernel_supports_stacking) { + bool stack; + + if (!parse_label(&stack, &ns, &name, + tbuf.c_str(), false)) { + return FALSE; + } + + if (stack) { + fprintf(stderr, + _("The current kernel does not support stacking of named transitions: %s\n"), + tbuf.c_str()); + return FALSE; + } + + if (ns) + vec[index++] = ns; + vec[index++] = name; + } else { + vec[index++] = tbuf.c_str(); + } /* regular change_profile rule */ if (!dfarules->add_rule_vec(entry->deny, AA_CHANGE_PROFILE | AA_ONEXEC, 0, index - 1, &vec[1], dfaflags)) diff --git a/parser/parser_yacc.y b/parser/parser_yacc.y index 44793f73a..2d950664b 100644 --- a/parser/parser_yacc.y +++ b/parser/parser_yacc.y @@ -311,7 +311,7 @@ profile_base: TOK_ID opt_id_or_var flags TOK_OPEN rules TOK_CLOSE yyerror(_("Memory allocation error.")); } - parse_label(&self_stack, &prof->ns, &prof->name, $1); + parse_label(&self_stack, &prof->ns, &prof->name, $1, true); free($1); if (self_stack) {