Skip to content

Commit

Permalink
ima: ima/lsm policy rule loading logic bug fixes
Browse files Browse the repository at this point in the history
Keep the ima policy rules around from the beginning even if they appear
invalid at the time of loading, as they may become active after an lsm
policy load.  However, loading a custom IMA policy with unknown LSM
labels is only safe after we have transitioned from the "built-in"
policy rules to a custom IMA policy.

Patch also fixes the rule re-use during the lsm policy reload and makes
some prints a bit more human readable.

Changelog:
v4:
- Do not allow the initial policy load refer to non-existing lsm rules.
v3:
- Fix too wide policy rule matching for non-initialized LSMs
v2:
- Fix log prints

Fixes: b169424 ("ima: use the lsm policy update notifier")
Cc: Casey Schaufler <casey@schaufler-ca.com>
Reported-by: Mimi Zohar <zohar@linux.ibm.com>
Signed-off-by: Janne Karhunen <janne.karhunen@gmail.com>
Signed-off-by: Konsta Karsisto <konsta.karsisto@gmail.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
  • Loading branch information
jkrh authored and mimizohar committed Jan 22, 2020
1 parent 6beea7a commit 483ec26
Showing 1 changed file with 26 additions and 18 deletions.
44 changes: 26 additions & 18 deletions security/integrity/ima/ima_policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ static void ima_lsm_free_rule(struct ima_rule_entry *entry)
static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry)
{
struct ima_rule_entry *nentry;
int i, result;
int i;

nentry = kmalloc(sizeof(*nentry), GFP_KERNEL);
if (!nentry)
Expand All @@ -279,7 +279,7 @@ static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry)
memset(nentry->lsm, 0, FIELD_SIZEOF(struct ima_rule_entry, lsm));

for (i = 0; i < MAX_LSM_RULES; i++) {
if (!entry->lsm[i].rule)
if (!entry->lsm[i].args_p)
continue;

nentry->lsm[i].type = entry->lsm[i].type;
Expand All @@ -288,13 +288,13 @@ static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry)
if (!nentry->lsm[i].args_p)
goto out_err;

result = security_filter_rule_init(nentry->lsm[i].type,
Audit_equal,
nentry->lsm[i].args_p,
&nentry->lsm[i].rule);
if (result == -EINVAL)
pr_warn("ima: rule for LSM \'%d\' is undefined\n",
entry->lsm[i].type);
security_filter_rule_init(nentry->lsm[i].type,
Audit_equal,
nentry->lsm[i].args_p,
&nentry->lsm[i].rule);
if (!nentry->lsm[i].rule)
pr_warn("rule for LSM \'%s\' is undefined\n",
(char *)entry->lsm[i].args_p);
}
return nentry;

Expand Down Expand Up @@ -331,7 +331,7 @@ static void ima_lsm_update_rules(void)
list_for_each_entry_safe(entry, e, &ima_policy_rules, list) {
needs_update = 0;
for (i = 0; i < MAX_LSM_RULES; i++) {
if (entry->lsm[i].rule) {
if (entry->lsm[i].args_p) {
needs_update = 1;
break;
}
Expand All @@ -341,8 +341,7 @@ static void ima_lsm_update_rules(void)

result = ima_lsm_update_rule(entry);
if (result) {
pr_err("ima: lsm rule update error %d\n",
result);
pr_err("lsm rule update error %d\n", result);
return;
}
}
Expand Down Expand Up @@ -403,7 +402,7 @@ static bool ima_match_keyring(struct ima_rule_entry *rule,
}

/**
* ima_match_rules - determine whether an inode matches the measure rule.
* ima_match_rules - determine whether an inode matches the policy rule.
* @rule: a pointer to a rule
* @inode: a pointer to an inode
* @cred: a pointer to a credentials structure for user validation
Expand Down Expand Up @@ -466,9 +465,12 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode,
int rc = 0;
u32 osid;

if (!rule->lsm[i].rule)
continue;

if (!rule->lsm[i].rule) {
if (!rule->lsm[i].args_p)
continue;
else
return false;
}
switch (i) {
case LSM_OBJ_USER:
case LSM_OBJ_ROLE:
Expand Down Expand Up @@ -880,8 +882,14 @@ static int ima_lsm_rule_init(struct ima_rule_entry *entry,
entry->lsm[lsm_rule].args_p,
&entry->lsm[lsm_rule].rule);
if (!entry->lsm[lsm_rule].rule) {
kfree(entry->lsm[lsm_rule].args_p);
return -EINVAL;
pr_warn("rule for LSM \'%s\' is undefined\n",
(char *)entry->lsm[lsm_rule].args_p);

if (ima_rules == &ima_default_rules) {
kfree(entry->lsm[lsm_rule].args_p);
result = -EINVAL;
} else
result = 0;
}

return result;
Expand Down

0 comments on commit 483ec26

Please sign in to comment.