mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-30 22:05:27 +00:00
parser: add support for matching based on extended file attributes
Add userland support for matching based on extended file attributes. This leverages DFA based matching already in the kernel: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=8e51f908 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=73f488cd Matching is exposed via flags on the profile: /usr/bin/* xattrs=(user.foo=bar user.bar=**) { # ... } Profiles list the set of extended attributes that a file MUST have, and a regex to match the value of that extended attributes. Additional extended attributes on the file don't effect the match. Signed-off-by: Eric Chiang <ericchiang@google.com>
This commit is contained in:
@@ -432,12 +432,29 @@ static const char *local_name(const char *name)
|
||||
return name;
|
||||
}
|
||||
|
||||
/*
|
||||
* get_xattr_value returns the value of an xattr expression, performing NULL
|
||||
* checks along the way. The method returns NULL if the xattr match doesn't
|
||||
* have an xattrs (though this case currently isn't permitted by the parser).
|
||||
*/
|
||||
char *get_xattr_value(struct cond_entry *entry)
|
||||
{
|
||||
if (!entry->eq)
|
||||
return NULL;
|
||||
if (!entry->vals)
|
||||
return NULL;
|
||||
return entry->vals->value;
|
||||
}
|
||||
|
||||
static int process_profile_name_xmatch(Profile *prof)
|
||||
{
|
||||
std::string tbuf;
|
||||
pattern_t ptype;
|
||||
const char *name;
|
||||
|
||||
struct cond_entry *entry;
|
||||
const char *xattr_value;
|
||||
|
||||
/* don't filter_slashes for profile names */
|
||||
if (prof->attachment)
|
||||
name = prof->attachment;
|
||||
@@ -451,7 +468,7 @@ static int process_profile_name_xmatch(Profile *prof)
|
||||
if (ptype == ePatternInvalid) {
|
||||
PERROR(_("%s: Invalid profile name '%s' - bad regular expression\n"), progname, name);
|
||||
return FALSE;
|
||||
} else if (ptype == ePatternBasic && !(prof->altnames || prof->attachment)) {
|
||||
} else if (ptype == ePatternBasic && !(prof->altnames || prof->attachment || prof->xattrs.list)) {
|
||||
/* no regex so do not set xmatch */
|
||||
prof->xmatch = NULL;
|
||||
prof->xmatch_len = 0;
|
||||
@@ -479,6 +496,28 @@ static int process_profile_name_xmatch(Profile *prof)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (prof->xattrs.list) {
|
||||
for (entry = prof->xattrs.list; entry; entry = entry->next) {
|
||||
xattr_value = get_xattr_value(entry);
|
||||
if (!xattr_value)
|
||||
xattr_value = "**"; // Default to allowing any value.
|
||||
/* len is measured because it's required to
|
||||
* convert the regex to pcre, but doesn't impact
|
||||
* xmatch_len. The kernel uses the number of
|
||||
* xattrs matched to prioritized in addition to
|
||||
* xmatch_len.
|
||||
*/
|
||||
int len;
|
||||
tbuf.clear();
|
||||
convert_aaregex_to_pcre(xattr_value, 0,
|
||||
glob_default, tbuf,
|
||||
&len);
|
||||
if (!rules->append_rule(tbuf.c_str(), dfaflags)) {
|
||||
delete rules;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
prof->xmatch = rules->create_dfa(&prof->xmatch_size, &prof->xmatch_len, dfaflags);
|
||||
delete rules;
|
||||
if (!prof->xmatch)
|
||||
|
Reference in New Issue
Block a user