mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-22 01:57:43 +00:00
Merge 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> MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1756 Approved-by: Steve Beattie <steve+gitlab@nxnw.org> Merged-by: Steve Beattie <steve+gitlab@nxnw.org>
This commit is contained in:
commit
d61295a249
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 '/'
|
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)
|
int variable::expand_by_alternation(char **name)
|
||||||
{
|
{
|
||||||
std::string expanded_name = "";
|
std::string expanded_name = "";
|
||||||
bool filter_leading_slash = false;
|
bool filter_leading_slash = false;
|
||||||
bool filter_trailing_slash = false;
|
bool filter_trailing_slash = false;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
if (!name) {
|
if (!name) {
|
||||||
PERROR("ASSERT: name to be expanded cannot be NULL\n");
|
PERROR("ASSERT: name to be expanded cannot be NULL\n");
|
||||||
@ -226,8 +238,6 @@ int variable::expand_by_alternation(char **name)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(*name);
|
|
||||||
|
|
||||||
size_t setsize = ref->expanded.size();
|
size_t setsize = ref->expanded.size();
|
||||||
auto i = ref->expanded.begin();
|
auto i = ref->expanded.begin();
|
||||||
|
|
||||||
@ -252,15 +262,19 @@ int variable::expand_by_alternation(char **name)
|
|||||||
if (setsize > 1) {
|
if (setsize > 1) {
|
||||||
expanded_name += "}";
|
expanded_name += "}";
|
||||||
}
|
}
|
||||||
|
/* don't include prefix */
|
||||||
expanded_name = prefix + expanded_name + suffix;
|
expanded_name = expanded_name + suffix;
|
||||||
*name = strdup(expanded_name.c_str());
|
ret = copy_value_to_name(expanded_name, name);
|
||||||
if (!*name) {
|
if (ret)
|
||||||
errno = ENOMEM;
|
return ret;
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
/* recursive until no variables are found in *name */
|
/* 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()
|
int variable::expand_variable()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user