/* Check xattr value */
state = aa_dfa_match_len(profile->xmatch, state, value,
size);
- perm = dfa_user_allow(profile->xmatch, state);
+ perm = profile->xmatch_perms[state];
if (!(perm & MAY_EXEC)) {
ret = -EINVAL;
goto out;
state = aa_dfa_leftmatch(profile->xmatch, DFA_START,
name, &count);
- perm = dfa_user_allow(profile->xmatch, state);
+ perm = profile->xmatch_perms[state];
/* any accepting state means a valid match. */
if (perm & MAY_EXEC) {
int ret = 0;
* @attach: human readable attachment string
* @xmatch: optional extended matching for unconfined executables names
* @xmatch_len: xmatch prefix len, used to determine xmatch priority
+ * @xmatch_perms: precomputed permissions for the xmatch DFA indexed by state
* @audit: the auditing mode of the profile
* @mode: the enforcement mode of the profile
* @path_flags: flags controlling path generation behavior
const char *attach;
struct aa_dfa *xmatch;
unsigned int xmatch_len;
+ u32 *xmatch_perms;
enum audit_mode audit;
long mode;
u32 path_flags;
kfree_sensitive(profile->secmark);
kfree_sensitive(profile->dirname);
aa_put_dfa(profile->xmatch);
+ kvfree(profile->xmatch_perms);
aa_put_dfa(profile->policy.dfa);
if (profile->data) {
return strcmp(data->key, *key);
}
+static u32 *aa_compute_xmatch_perms(struct aa_dfa *xmatch)
+{
+ u32 *perms_table;
+ int state;
+ int state_count = xmatch->tables[YYTD_ID_BASE]->td_lolen;
+
+ // DFAs are restricted from having a state_count of less than 2
+ perms_table = kvcalloc(state_count, sizeof(u32), GFP_KERNEL);
+
+ // Since perms_table is initialized with zeroes via kvcalloc(), we can
+ // skip the trap state (state == 0)
+ for (state = 1; state < state_count; state++)
+ perms_table[state] = dfa_user_allow(xmatch, state);
+
+ return perms_table;
+}
+
/**
* unpack_profile - unpack a serialized profile
* @e: serialized data extent information (NOT NULL)
info = "bad xmatch";
goto fail;
}
- /* xmatch_len is not optional if xmatch is set */
+ /* neither xmatch_len not xmatch_perms are optional if xmatch is set */
if (profile->xmatch) {
if (!unpack_u32(e, &tmp, NULL)) {
info = "missing xmatch len";
goto fail;
}
profile->xmatch_len = tmp;
+
+ profile->xmatch_perms = aa_compute_xmatch_perms(
+ profile->xmatch);
}
/* disconnected attachment string is optional */