aboutsummaryrefslogtreecommitdiffstats
path: root/security/integrity
diff options
context:
space:
mode:
authorMimi Zohar <zohar@linux.vnet.ibm.com>2013-01-03 14:19:09 -0500
committerMimi Zohar <zohar@linux.vnet.ibm.com>2013-01-16 15:47:03 -0500
commit7163a993840f0906d4ce1e3f193575c99dac21e1 (patch)
tree3c1c04f5da24cf2492b20b861c9974549978436c /security/integrity
parentcf9ce948f47640797bd19980e1d99c6d17d0bdc3 (diff)
ima: re-initialize IMA policy LSM info
Although the IMA policy does not change, the LSM policy can be reloaded, leaving the IMA LSM based rules referring to the old, stale LSM policy. This patch updates the IMA LSM based rules to reflect the reloaded LSM policy. Reported-by: Sven Vermeulen <sven.vermeulen@siphos.be> tested-by: Sven Vermeulen <sven.vermeulen@siphos.be> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com> Cc: Eric Paris <eparis@parisplace.org> Cc: Casey Schaufler <casey@schaufler-ca.com>
Diffstat (limited to 'security/integrity')
-rw-r--r--security/integrity/ima/ima_policy.c68
1 files changed, 58 insertions, 10 deletions
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index af7d182d5a46..70f888de880d 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -49,6 +49,7 @@ struct ima_rule_entry {
49 kuid_t fowner; 49 kuid_t fowner;
50 struct { 50 struct {
51 void *rule; /* LSM file metadata specific */ 51 void *rule; /* LSM file metadata specific */
52 void *args_p; /* audit value */
52 int type; /* audit type */ 53 int type; /* audit type */
53 } lsm[MAX_LSM_RULES]; 54 } lsm[MAX_LSM_RULES];
54}; 55};
@@ -119,6 +120,35 @@ static int __init default_appraise_policy_setup(char *str)
119} 120}
120__setup("ima_appraise_tcb", default_appraise_policy_setup); 121__setup("ima_appraise_tcb", default_appraise_policy_setup);
121 122
123/*
124 * Although the IMA policy does not change, the LSM policy can be
125 * reloaded, leaving the IMA LSM based rules referring to the old,
126 * stale LSM policy.
127 *
128 * Update the IMA LSM based rules to reflect the reloaded LSM policy.
129 * We assume the rules still exist; and BUG_ON() if they don't.
130 */
131static void ima_lsm_update_rules(void)
132{
133 struct ima_rule_entry *entry, *tmp;
134 int result;
135 int i;
136
137 mutex_lock(&ima_rules_mutex);
138 list_for_each_entry_safe(entry, tmp, &ima_policy_rules, list) {
139 for (i = 0; i < MAX_LSM_RULES; i++) {
140 if (!entry->lsm[i].rule)
141 continue;
142 result = security_filter_rule_init(entry->lsm[i].type,
143 Audit_equal,
144 entry->lsm[i].args_p,
145 &entry->lsm[i].rule);
146 BUG_ON(!entry->lsm[i].rule);
147 }
148 }
149 mutex_unlock(&ima_rules_mutex);
150}
151
122/** 152/**
123 * ima_match_rules - determine whether an inode matches the measure rule. 153 * ima_match_rules - determine whether an inode matches the measure rule.
124 * @rule: a pointer to a rule 154 * @rule: a pointer to a rule
@@ -149,10 +179,11 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
149 for (i = 0; i < MAX_LSM_RULES; i++) { 179 for (i = 0; i < MAX_LSM_RULES; i++) {
150 int rc = 0; 180 int rc = 0;
151 u32 osid, sid; 181 u32 osid, sid;
182 int retried = 0;
152 183
153 if (!rule->lsm[i].rule) 184 if (!rule->lsm[i].rule)
154 continue; 185 continue;
155 186retry:
156 switch (i) { 187 switch (i) {
157 case LSM_OBJ_USER: 188 case LSM_OBJ_USER:
158 case LSM_OBJ_ROLE: 189 case LSM_OBJ_ROLE:
@@ -176,6 +207,11 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
176 default: 207 default:
177 break; 208 break;
178 } 209 }
210 if ((rc < 0) && (!retried)) {
211 retried = 1;
212 ima_lsm_update_rules();
213 goto retry;
214 }
179 if (!rc) 215 if (!rc)
180 return false; 216 return false;
181 } 217 }
@@ -306,19 +342,27 @@ static match_table_t policy_tokens = {
306}; 342};
307 343
308static int ima_lsm_rule_init(struct ima_rule_entry *entry, 344static int ima_lsm_rule_init(struct ima_rule_entry *entry,
309 char *args, int lsm_rule, int audit_type) 345 substring_t *args, int lsm_rule, int audit_type)
310{ 346{
311 int result; 347 int result;
312 348
313 if (entry->lsm[lsm_rule].rule) 349 if (entry->lsm[lsm_rule].rule)
314 return -EINVAL; 350 return -EINVAL;
315 351
352 entry->lsm[lsm_rule].args_p = match_strdup(args);
353 if (!entry->lsm[lsm_rule].args_p)
354 return -ENOMEM;
355
316 entry->lsm[lsm_rule].type = audit_type; 356 entry->lsm[lsm_rule].type = audit_type;
317 result = security_filter_rule_init(entry->lsm[lsm_rule].type, 357 result = security_filter_rule_init(entry->lsm[lsm_rule].type,
318 Audit_equal, args, 358 Audit_equal,
359 entry->lsm[lsm_rule].args_p,
319 &entry->lsm[lsm_rule].rule); 360 &entry->lsm[lsm_rule].rule);
320 if (!entry->lsm[lsm_rule].rule) 361 if (!entry->lsm[lsm_rule].rule) {
362 kfree(entry->lsm[lsm_rule].args_p);
321 return -EINVAL; 363 return -EINVAL;
364 }
365
322 return result; 366 return result;
323} 367}
324 368
@@ -481,37 +525,37 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
481 break; 525 break;
482 case Opt_obj_user: 526 case Opt_obj_user:
483 ima_log_string(ab, "obj_user", args[0].from); 527 ima_log_string(ab, "obj_user", args[0].from);
484 result = ima_lsm_rule_init(entry, args[0].from, 528 result = ima_lsm_rule_init(entry, args,
485 LSM_OBJ_USER, 529 LSM_OBJ_USER,
486 AUDIT_OBJ_USER); 530 AUDIT_OBJ_USER);
487 break; 531 break;
488 case Opt_obj_role: 532 case Opt_obj_role:
489 ima_log_string(ab, "obj_role", args[0].from); 533 ima_log_string(ab, "obj_role", args[0].from);
490 result = ima_lsm_rule_init(entry, args[0].from, 534 result = ima_lsm_rule_init(entry, args,
491 LSM_OBJ_ROLE, 535 LSM_OBJ_ROLE,
492 AUDIT_OBJ_ROLE); 536 AUDIT_OBJ_ROLE);
493 break; 537 break;
494 case Opt_obj_type: 538 case Opt_obj_type:
495 ima_log_string(ab, "obj_type", args[0].from); 539 ima_log_string(ab, "obj_type", args[0].from);
496 result = ima_lsm_rule_init(entry, args[0].from, 540 result = ima_lsm_rule_init(entry, args,
497 LSM_OBJ_TYPE, 541 LSM_OBJ_TYPE,
498 AUDIT_OBJ_TYPE); 542 AUDIT_OBJ_TYPE);
499 break; 543 break;
500 case Opt_subj_user: 544 case Opt_subj_user:
501 ima_log_string(ab, "subj_user", args[0].from); 545 ima_log_string(ab, "subj_user", args[0].from);
502 result = ima_lsm_rule_init(entry, args[0].from, 546 result = ima_lsm_rule_init(entry, args,
503 LSM_SUBJ_USER, 547 LSM_SUBJ_USER,
504 AUDIT_SUBJ_USER); 548 AUDIT_SUBJ_USER);
505 break; 549 break;
506 case Opt_subj_role: 550 case Opt_subj_role:
507 ima_log_string(ab, "subj_role", args[0].from); 551 ima_log_string(ab, "subj_role", args[0].from);
508 result = ima_lsm_rule_init(entry, args[0].from, 552 result = ima_lsm_rule_init(entry, args,
509 LSM_SUBJ_ROLE, 553 LSM_SUBJ_ROLE,
510 AUDIT_SUBJ_ROLE); 554 AUDIT_SUBJ_ROLE);
511 break; 555 break;
512 case Opt_subj_type: 556 case Opt_subj_type:
513 ima_log_string(ab, "subj_type", args[0].from); 557 ima_log_string(ab, "subj_type", args[0].from);
514 result = ima_lsm_rule_init(entry, args[0].from, 558 result = ima_lsm_rule_init(entry, args,
515 LSM_SUBJ_TYPE, 559 LSM_SUBJ_TYPE,
516 AUDIT_SUBJ_TYPE); 560 AUDIT_SUBJ_TYPE);
517 break; 561 break;
@@ -589,9 +633,13 @@ ssize_t ima_parse_add_rule(char *rule)
589void ima_delete_rules(void) 633void ima_delete_rules(void)
590{ 634{
591 struct ima_rule_entry *entry, *tmp; 635 struct ima_rule_entry *entry, *tmp;
636 int i;
592 637
593 mutex_lock(&ima_rules_mutex); 638 mutex_lock(&ima_rules_mutex);
594 list_for_each_entry_safe(entry, tmp, &ima_policy_rules, list) { 639 list_for_each_entry_safe(entry, tmp, &ima_policy_rules, list) {
640 for (i = 0; i < MAX_LSM_RULES; i++)
641 kfree(entry->lsm[i].args_p);
642
595 list_del(&entry->list); 643 list_del(&entry->list);
596 kfree(entry); 644 kfree(entry);
597 } 645 }