2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-08-22 01:57:43 +00:00

parser: Support stacking in exec and change_profile rules

Allow for a leading '&' character to be present in the named transition
target strings to indicate that the transition should stack the current
profile with the specified profile.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Acked-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
Tyler Hicks 2016-03-18 17:28:51 -05:00
parent a83d03a6a7
commit 00fb4e94ab
8 changed files with 56 additions and 8 deletions

View File

@ -386,7 +386,7 @@ extern char *process_var(const char *var);
extern int parse_mode(const char *mode); 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); 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); bool label_contains_ns(const char *label);
void parse_label(char **ns, char **name, const char *label); void parse_label(bool *stack, char **ns, char **name, const char *label);
extern struct cod_entry *new_entry(char *id, int mode, char *link_id); 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 */ /* returns -1 if value != true or false, otherwise 0 == false, 1 == true */

View File

@ -192,6 +192,7 @@ OPEN_BRACE \{
CLOSE_BRACE \} CLOSE_BRACE \}
SLASH \/ SLASH \/
COLON : COLON :
AMPERSAND &
END_OF_RULE [,] END_OF_RULE [,]
RANGE - RANGE -
MODE_CHARS ([RrWwaLlMmkXx])|(([Pp]|[Cc])[Xx])|(([Pp]|[Cc])?([IiUu])[Xx]) MODE_CHARS ([RrWwaLlMmkXx])|(([Pp]|[Cc])[Xx])|(([Pp]|[Cc])?([IiUu])[Xx])
@ -225,8 +226,8 @@ SET_VAR_PREFIX @
SET_VARIABLE {SET_VAR_PREFIX}(\{{VARIABLE_NAME}\}|{VARIABLE_NAME}) SET_VARIABLE {SET_VAR_PREFIX}(\{{VARIABLE_NAME}\}|{VARIABLE_NAME})
BOOL_VARIABLE $(\{{VARIABLE_NAME}\}|{VARIABLE_NAME}) BOOL_VARIABLE $(\{{VARIABLE_NAME}\}|{VARIABLE_NAME})
LABEL (\/|{SET_VARIABLE}{POST_VAR_ID}|{COLON}){ID}* LABEL (\/|{SET_VARIABLE}{POST_VAR_ID}|{COLON}|{AMPERSAND}){ID}*
QUOTED_LABEL \"(\/|{SET_VAR_PREFIX}|{COLON})([^\0"]|\\\")*\" QUOTED_LABEL \"(\/|{SET_VAR_PREFIX}|{COLON}|{AMPERSAND})([^\0"]|\\\")*\"
OPEN_PAREN \( OPEN_PAREN \(
CLOSE_PAREN \) CLOSE_PAREN \)

View File

@ -571,6 +571,7 @@ int parse_X_mode(const char *X, int valid, const char *str_mode, int *mode, int
/** /**
* parse_label - break a label down to the namespace and profile name * parse_label - break a label down to the namespace and profile name
* @stack: Will be true if the first char in @label is '&' to indicate stacking
* @ns: Will point to the first char in the namespace upon return or NULL * @ns: Will point to the first char in the namespace upon return or NULL
* if no namespace is present * if no namespace is present
* @ns_len: Number of chars in the namespace string or 0 if no namespace * @ns_len: Number of chars in the namespace string or 0 if no namespace
@ -589,7 +590,8 @@ int parse_X_mode(const char *X, int valid, const char *str_mode, int *mode, int
* 2) Namespace is empty meaning @label starts with "::" * 2) Namespace is empty meaning @label starts with "::"
* 3) Profile name is empty * 3) Profile name is empty
*/ */
static int _parse_label(char **ns, size_t *ns_len, static int _parse_label(bool *stack,
char **ns, size_t *ns_len,
char **name, size_t *name_len, char **name, size_t *name_len,
const char *label) const char *label)
{ {
@ -597,6 +599,17 @@ static int _parse_label(char **ns, size_t *ns_len,
const char *ns_start = NULL; const char *ns_start = NULL;
const char *ns_end = NULL; const char *ns_end = NULL;
if (label[0] == '&') {
/**
* Leading ampersand means that the current profile should
* be stacked with the rest of the label
*/
*stack = true;
label++;
} else {
*stack = false;
}
if (label[0] != ':') { if (label[0] != ':') {
/* There is no namespace specified in the label */ /* There is no namespace specified in the label */
name_start = label; name_start = label;
@ -639,15 +652,16 @@ static int _parse_label(char **ns, size_t *ns_len,
bool label_contains_ns(const char *label) bool label_contains_ns(const char *label)
{ {
bool stack = false;
char *ns = NULL; char *ns = NULL;
char *name = NULL; char *name = NULL;
size_t ns_len = 0; size_t ns_len = 0;
size_t name_len = 0; size_t name_len = 0;
return _parse_label(&ns, &ns_len, &name, &name_len, label) == 0 && ns; return _parse_label(&stack, &ns, &ns_len, &name, &name_len, label) == 0 && ns;
} }
void parse_label(char **_ns, char **_name, const char *label) void parse_label(bool *_stack, char **_ns, char **_name, const char *label)
{ {
char *ns = NULL; char *ns = NULL;
char *name = NULL; char *name = NULL;
@ -655,7 +669,7 @@ void parse_label(char **_ns, char **_name, const char *label)
size_t name_len = 0; size_t name_len = 0;
int res; int res;
res = _parse_label(&ns, &ns_len, &name, &name_len, label); res = _parse_label(_stack, &ns, &ns_len, &name, &name_len, label);
if (res == 1) { if (res == 1) {
yyerror(_("Namespace not terminated: %s\n"), label); yyerror(_("Namespace not terminated: %s\n"), label);
} else if (res == 2) { } else if (res == 2) {

View File

@ -305,14 +305,19 @@ opt_id_or_var: { /* nothing */ $$ = NULL; }
profile_base: TOK_ID opt_id_or_var flags TOK_OPEN rules TOK_CLOSE profile_base: TOK_ID opt_id_or_var flags TOK_OPEN rules TOK_CLOSE
{ {
Profile *prof = $5; Profile *prof = $5;
bool self_stack = false;
if (!prof) { if (!prof) {
yyerror(_("Memory allocation error.")); yyerror(_("Memory allocation error."));
} }
parse_label(&prof->ns, &prof->name, $1); parse_label(&self_stack, &prof->ns, &prof->name, $1);
free($1); free($1);
if (self_stack) {
yyerror(_("Profile names must begin with a '/' or a namespace"));
}
/* Honor the --namespace-string command line option */ /* Honor the --namespace-string command line option */
if (profile_ns) { if (profile_ns) {
/** /**

View File

@ -0,0 +1,7 @@
#
#=DESCRIPTION change_profile w/ stacking
#=EXRESULT PASS
#
/usr/bin/foo {
change_profile -> &/bin/foo,
}

View File

@ -0,0 +1,7 @@
#
#=DESCRIPTION change_profile w/ stacking
#=EXRESULT PASS
#
/usr/bin/foo {
change_profile -> &bar,
}

View File

@ -0,0 +1,7 @@
#
#=DESCRIPTION change_profile w/ stacking
#=EXRESULT PASS
#
/usr/bin/foo {
change_profile /bin/foo -> &bar,
}

View File

@ -0,0 +1,7 @@
#
#=Description basic file exec rule with stacking target
#=EXRESULT PASS
#
/usr/bin/foo {
/bin/bar px -> &baz,
}