mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-22 10:07:12 +00:00
parser: fix variable expansion
When the variable was being expanded, it needed to be reevaluated to check if there was still unresolved variables. That allowed for a weird bug to happen: If the string contained a variable preceded by @, like in "user@@{uid}" and the variable was resolved to a case where { is used, like in @{uid}={[0-9],[1-9][0-9]}, then on the second pass, the parser would try to resolve the following variable @{[0-9],[1-9][0-9]}, which is incorrect behavior. Fix it by not including part of the string that was already resolved on the subsequent passes. Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
This commit is contained in:
parent
61e09c6ffa
commit
a2f2ca6119
7
parser/tst/simple_tests/vars/vars_file_evaluation_17.sd
Normal file
7
parser/tst/simple_tests/vars/vars_file_evaluation_17.sd
Normal file
@ -0,0 +1,7 @@
|
||||
#=DESCRIPTION expansion of alternation after extra, unescaped @
|
||||
#=EXRESULT PASS
|
||||
@{uid} = {[0-9],[1-9][0-9]}
|
||||
|
||||
/usr/bin/foo {
|
||||
/sys/fs/cgroup/user.slice/user-@{uid}.slice/user@@{uid}.service/cpu.max r,
|
||||
}
|
@ -189,11 +189,23 @@ static void trim_trailing_slash(std::string& str)
|
||||
str.clear(); // str is all '/'
|
||||
}
|
||||
|
||||
int copy_value_to_name(std::string value, char **name)
|
||||
{
|
||||
free(*name);
|
||||
*name = strdup(value.c_str());
|
||||
if (!*name) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int variable::expand_by_alternation(char **name)
|
||||
{
|
||||
std::string expanded_name = "";
|
||||
bool filter_leading_slash = false;
|
||||
bool filter_trailing_slash = false;
|
||||
int ret = 0;
|
||||
|
||||
if (!name) {
|
||||
PERROR("ASSERT: name to be expanded cannot be NULL\n");
|
||||
@ -226,8 +238,6 @@ int variable::expand_by_alternation(char **name)
|
||||
return 1;
|
||||
}
|
||||
|
||||
free(*name);
|
||||
|
||||
size_t setsize = ref->expanded.size();
|
||||
auto i = ref->expanded.begin();
|
||||
|
||||
@ -252,15 +262,19 @@ int variable::expand_by_alternation(char **name)
|
||||
if (setsize > 1) {
|
||||
expanded_name += "}";
|
||||
}
|
||||
|
||||
expanded_name = prefix + expanded_name + suffix;
|
||||
*name = strdup(expanded_name.c_str());
|
||||
if (!*name) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
/* don't include prefix */
|
||||
expanded_name = expanded_name + suffix;
|
||||
ret = copy_value_to_name(expanded_name, name);
|
||||
if (ret)
|
||||
return ret;
|
||||
/* recursive until no variables are found in *name */
|
||||
return expand_by_alternation(name);
|
||||
ret = expand_by_alternation(name);
|
||||
if (ret == 0) {
|
||||
/* return prefix to name */
|
||||
expanded_name = prefix + std::string(*name);
|
||||
ret = copy_value_to_name(expanded_name, name);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int variable::expand_variable()
|
||||
|
Loading…
x
Reference in New Issue
Block a user