Skip to content

Commit 483ec26

Browse files
jkrhmimizohar
authored andcommitted
ima: ima/lsm policy rule loading logic bug fixes
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 <[email protected]> Reported-by: Mimi Zohar <[email protected]> Signed-off-by: Janne Karhunen <[email protected]> Signed-off-by: Konsta Karsisto <[email protected]> Signed-off-by: Mimi Zohar <[email protected]>
1 parent 6beea7a commit 483ec26

File tree

1 file changed

+26
-18
lines changed

1 file changed

+26
-18
lines changed

security/integrity/ima/ima_policy.c

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ static void ima_lsm_free_rule(struct ima_rule_entry *entry)
265265
static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry)
266266
{
267267
struct ima_rule_entry *nentry;
268-
int i, result;
268+
int i;
269269

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

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

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

291-
result = security_filter_rule_init(nentry->lsm[i].type,
292-
Audit_equal,
293-
nentry->lsm[i].args_p,
294-
&nentry->lsm[i].rule);
295-
if (result == -EINVAL)
296-
pr_warn("ima: rule for LSM \'%d\' is undefined\n",
297-
entry->lsm[i].type);
291+
security_filter_rule_init(nentry->lsm[i].type,
292+
Audit_equal,
293+
nentry->lsm[i].args_p,
294+
&nentry->lsm[i].rule);
295+
if (!nentry->lsm[i].rule)
296+
pr_warn("rule for LSM \'%s\' is undefined\n",
297+
(char *)entry->lsm[i].args_p);
298298
}
299299
return nentry;
300300

@@ -331,7 +331,7 @@ static void ima_lsm_update_rules(void)
331331
list_for_each_entry_safe(entry, e, &ima_policy_rules, list) {
332332
needs_update = 0;
333333
for (i = 0; i < MAX_LSM_RULES; i++) {
334-
if (entry->lsm[i].rule) {
334+
if (entry->lsm[i].args_p) {
335335
needs_update = 1;
336336
break;
337337
}
@@ -341,8 +341,7 @@ static void ima_lsm_update_rules(void)
341341

342342
result = ima_lsm_update_rule(entry);
343343
if (result) {
344-
pr_err("ima: lsm rule update error %d\n",
345-
result);
344+
pr_err("lsm rule update error %d\n", result);
346345
return;
347346
}
348347
}
@@ -403,7 +402,7 @@ static bool ima_match_keyring(struct ima_rule_entry *rule,
403402
}
404403

405404
/**
406-
* ima_match_rules - determine whether an inode matches the measure rule.
405+
* ima_match_rules - determine whether an inode matches the policy rule.
407406
* @rule: a pointer to a rule
408407
* @inode: a pointer to an inode
409408
* @cred: a pointer to a credentials structure for user validation
@@ -466,9 +465,12 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode,
466465
int rc = 0;
467466
u32 osid;
468467

469-
if (!rule->lsm[i].rule)
470-
continue;
471-
468+
if (!rule->lsm[i].rule) {
469+
if (!rule->lsm[i].args_p)
470+
continue;
471+
else
472+
return false;
473+
}
472474
switch (i) {
473475
case LSM_OBJ_USER:
474476
case LSM_OBJ_ROLE:
@@ -880,8 +882,14 @@ static int ima_lsm_rule_init(struct ima_rule_entry *entry,
880882
entry->lsm[lsm_rule].args_p,
881883
&entry->lsm[lsm_rule].rule);
882884
if (!entry->lsm[lsm_rule].rule) {
883-
kfree(entry->lsm[lsm_rule].args_p);
884-
return -EINVAL;
885+
pr_warn("rule for LSM \'%s\' is undefined\n",
886+
(char *)entry->lsm[lsm_rule].args_p);
887+
888+
if (ima_rules == &ima_default_rules) {
889+
kfree(entry->lsm[lsm_rule].args_p);
890+
result = -EINVAL;
891+
} else
892+
result = 0;
885893
}
886894

887895
return result;

0 commit comments

Comments
 (0)