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:
parent
a83d03a6a7
commit
00fb4e94ab
@ -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 */
|
||||||
|
@ -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 \)
|
||||||
|
@ -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) {
|
||||||
|
@ -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) {
|
||||||
/**
|
/**
|
||||||
|
7
parser/tst/simple_tests/change_profile/stacking_ok_1.sd
Normal file
7
parser/tst/simple_tests/change_profile/stacking_ok_1.sd
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION change_profile w/ stacking
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/usr/bin/foo {
|
||||||
|
change_profile -> &/bin/foo,
|
||||||
|
}
|
7
parser/tst/simple_tests/change_profile/stacking_ok_2.sd
Normal file
7
parser/tst/simple_tests/change_profile/stacking_ok_2.sd
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION change_profile w/ stacking
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/usr/bin/foo {
|
||||||
|
change_profile -> &bar,
|
||||||
|
}
|
7
parser/tst/simple_tests/change_profile/stacking_ok_3.sd
Normal file
7
parser/tst/simple_tests/change_profile/stacking_ok_3.sd
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=DESCRIPTION change_profile w/ stacking
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/usr/bin/foo {
|
||||||
|
change_profile /bin/foo -> &bar,
|
||||||
|
}
|
7
parser/tst/simple_tests/file/stacking_ok_1.sd
Normal file
7
parser/tst/simple_tests/file/stacking_ok_1.sd
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=Description basic file exec rule with stacking target
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/usr/bin/foo {
|
||||||
|
/bin/bar px -> &baz,
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user