aboutsummaryrefslogtreecommitdiffstats
path: root/security/integrity
diff options
context:
space:
mode:
Diffstat (limited to 'security/integrity')
-rw-r--r--security/integrity/ima/ima_appraise.c5
-rw-r--r--security/integrity/ima/ima_policy.c151
2 files changed, 116 insertions, 40 deletions
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 4865f61f9044..681cb6e72257 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -36,7 +36,10 @@ __setup("ima_appraise=", default_appraise_setup);
36 */ 36 */
37int ima_must_appraise(struct inode *inode, enum ima_hooks func, int mask) 37int ima_must_appraise(struct inode *inode, enum ima_hooks func, int mask)
38{ 38{
39 return 0; 39 if (!ima_appraise)
40 return 0;
41
42 return ima_match_policy(inode, func, mask, IMA_APPRAISE);
40} 43}
41 44
42static void ima_fix_xattr(struct dentry *dentry, 45static void ima_fix_xattr(struct dentry *dentry,
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 3e22e17da295..0d6d60b4ba6f 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -24,6 +24,7 @@
24#define IMA_MASK 0x0002 24#define IMA_MASK 0x0002
25#define IMA_FSMAGIC 0x0004 25#define IMA_FSMAGIC 0x0004
26#define IMA_UID 0x0008 26#define IMA_UID 0x0008
27#define IMA_FOWNER 0x0010
27 28
28#define UNKNOWN 0 29#define UNKNOWN 0
29#define MEASURE 1 /* same as IMA_MEASURE */ 30#define MEASURE 1 /* same as IMA_MEASURE */
@@ -38,7 +39,7 @@ enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE,
38 LSM_SUBJ_USER, LSM_SUBJ_ROLE, LSM_SUBJ_TYPE 39 LSM_SUBJ_USER, LSM_SUBJ_ROLE, LSM_SUBJ_TYPE
39}; 40};
40 41
41struct ima_measure_rule_entry { 42struct ima_rule_entry {
42 struct list_head list; 43 struct list_head list;
43 int action; 44 int action;
44 unsigned int flags; 45 unsigned int flags;
@@ -46,6 +47,7 @@ struct ima_measure_rule_entry {
46 int mask; 47 int mask;
47 unsigned long fsmagic; 48 unsigned long fsmagic;
48 uid_t uid; 49 uid_t uid;
50 uid_t fowner;
49 struct { 51 struct {
50 void *rule; /* LSM file metadata specific */ 52 void *rule; /* LSM file metadata specific */
51 int type; /* audit type */ 53 int type; /* audit type */
@@ -54,7 +56,7 @@ struct ima_measure_rule_entry {
54 56
55/* 57/*
56 * Without LSM specific knowledge, the default policy can only be 58 * Without LSM specific knowledge, the default policy can only be
57 * written in terms of .action, .func, .mask, .fsmagic, and .uid 59 * written in terms of .action, .func, .mask, .fsmagic, .uid, and .fowner
58 */ 60 */
59 61
60/* 62/*
@@ -63,7 +65,7 @@ struct ima_measure_rule_entry {
63 * normal users can easily run the machine out of memory simply building 65 * normal users can easily run the machine out of memory simply building
64 * and running executables. 66 * and running executables.
65 */ 67 */
66static struct ima_measure_rule_entry default_rules[] = { 68static struct ima_rule_entry default_rules[] = {
67 {.action = DONT_MEASURE,.fsmagic = PROC_SUPER_MAGIC,.flags = IMA_FSMAGIC}, 69 {.action = DONT_MEASURE,.fsmagic = PROC_SUPER_MAGIC,.flags = IMA_FSMAGIC},
68 {.action = DONT_MEASURE,.fsmagic = SYSFS_MAGIC,.flags = IMA_FSMAGIC}, 70 {.action = DONT_MEASURE,.fsmagic = SYSFS_MAGIC,.flags = IMA_FSMAGIC},
69 {.action = DONT_MEASURE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC}, 71 {.action = DONT_MEASURE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC},
@@ -81,19 +83,41 @@ static struct ima_measure_rule_entry default_rules[] = {
81 .flags = IMA_FUNC | IMA_MASK | IMA_UID}, 83 .flags = IMA_FUNC | IMA_MASK | IMA_UID},
82}; 84};
83 85
84static LIST_HEAD(measure_default_rules); 86static struct ima_rule_entry default_appraise_rules[] = {
85static LIST_HEAD(measure_policy_rules); 87 {.action = DONT_APPRAISE,.fsmagic = PROC_SUPER_MAGIC,.flags = IMA_FSMAGIC},
86static struct list_head *ima_measure; 88 {.action = DONT_APPRAISE,.fsmagic = SYSFS_MAGIC,.flags = IMA_FSMAGIC},
89 {.action = DONT_APPRAISE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC},
90 {.action = DONT_APPRAISE,.fsmagic = TMPFS_MAGIC,.flags = IMA_FSMAGIC},
91 {.action = DONT_APPRAISE,.fsmagic = RAMFS_MAGIC,.flags = IMA_FSMAGIC},
92 {.action = DONT_APPRAISE,.fsmagic = DEVPTS_SUPER_MAGIC,.flags = IMA_FSMAGIC},
93 {.action = DONT_APPRAISE,.fsmagic = BINFMTFS_MAGIC,.flags = IMA_FSMAGIC},
94 {.action = DONT_APPRAISE,.fsmagic = SECURITYFS_MAGIC,.flags = IMA_FSMAGIC},
95 {.action = DONT_APPRAISE,.fsmagic = SELINUX_MAGIC,.flags = IMA_FSMAGIC},
96 {.action = DONT_APPRAISE,.fsmagic = CGROUP_SUPER_MAGIC,.flags = IMA_FSMAGIC},
97 {.action = APPRAISE,.fowner = 0,.flags = IMA_FOWNER},
98};
99
100static LIST_HEAD(ima_default_rules);
101static LIST_HEAD(ima_policy_rules);
102static struct list_head *ima_rules;
87 103
88static DEFINE_MUTEX(ima_measure_mutex); 104static DEFINE_MUTEX(ima_rules_mutex);
89 105
90static bool ima_use_tcb __initdata; 106static bool ima_use_tcb __initdata;
91static int __init default_policy_setup(char *str) 107static int __init default_measure_policy_setup(char *str)
92{ 108{
93 ima_use_tcb = 1; 109 ima_use_tcb = 1;
94 return 1; 110 return 1;
95} 111}
96__setup("ima_tcb", default_policy_setup); 112__setup("ima_tcb", default_measure_policy_setup);
113
114static bool ima_use_appraise_tcb __initdata;
115static int __init default_appraise_policy_setup(char *str)
116{
117 ima_use_appraise_tcb = 1;
118 return 1;
119}
120__setup("ima_appraise_tcb", default_appraise_policy_setup);
97 121
98/** 122/**
99 * ima_match_rules - determine whether an inode matches the measure rule. 123 * ima_match_rules - determine whether an inode matches the measure rule.
@@ -104,7 +128,7 @@ __setup("ima_tcb", default_policy_setup);
104 * 128 *
105 * Returns true on rule match, false on failure. 129 * Returns true on rule match, false on failure.
106 */ 130 */
107static bool ima_match_rules(struct ima_measure_rule_entry *rule, 131static bool ima_match_rules(struct ima_rule_entry *rule,
108 struct inode *inode, enum ima_hooks func, int mask) 132 struct inode *inode, enum ima_hooks func, int mask)
109{ 133{
110 struct task_struct *tsk = current; 134 struct task_struct *tsk = current;
@@ -120,6 +144,8 @@ static bool ima_match_rules(struct ima_measure_rule_entry *rule,
120 return false; 144 return false;
121 if ((rule->flags & IMA_UID) && rule->uid != cred->uid) 145 if ((rule->flags & IMA_UID) && rule->uid != cred->uid)
122 return false; 146 return false;
147 if ((rule->flags & IMA_FOWNER) && rule->fowner != inode->i_uid)
148 return false;
123 for (i = 0; i < MAX_LSM_RULES; i++) { 149 for (i = 0; i < MAX_LSM_RULES; i++) {
124 int rc = 0; 150 int rc = 0;
125 u32 osid, sid; 151 u32 osid, sid;
@@ -172,10 +198,10 @@ static bool ima_match_rules(struct ima_measure_rule_entry *rule,
172int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask, 198int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
173 int flags) 199 int flags)
174{ 200{
175 struct ima_measure_rule_entry *entry; 201 struct ima_rule_entry *entry;
176 int action = 0, actmask = flags | (flags << 1); 202 int action = 0, actmask = flags | (flags << 1);
177 203
178 list_for_each_entry(entry, ima_measure, list) { 204 list_for_each_entry(entry, ima_rules, list) {
179 205
180 if (!(entry->action & actmask)) 206 if (!(entry->action & actmask))
181 continue; 207 continue;
@@ -196,22 +222,31 @@ int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
196/** 222/**
197 * ima_init_policy - initialize the default measure rules. 223 * ima_init_policy - initialize the default measure rules.
198 * 224 *
199 * ima_measure points to either the measure_default_rules or the 225 * ima_rules points to either the ima_default_rules or the
200 * the new measure_policy_rules. 226 * the new ima_policy_rules.
201 */ 227 */
202void __init ima_init_policy(void) 228void __init ima_init_policy(void)
203{ 229{
204 int i, entries; 230 int i, measure_entries, appraise_entries;
205 231
206 /* if !ima_use_tcb set entries = 0 so we load NO default rules */ 232 /* if !ima_use_tcb set entries = 0 so we load NO default rules */
207 if (ima_use_tcb) 233 measure_entries = ima_use_tcb ? ARRAY_SIZE(default_rules) : 0;
208 entries = ARRAY_SIZE(default_rules); 234 appraise_entries = ima_use_appraise_tcb ?
209 else 235 ARRAY_SIZE(default_appraise_rules) : 0;
210 entries = 0; 236
211 237 for (i = 0; i < measure_entries + appraise_entries; i++) {
212 for (i = 0; i < entries; i++) 238 if (i < measure_entries)
213 list_add_tail(&default_rules[i].list, &measure_default_rules); 239 list_add_tail(&default_rules[i].list,
214 ima_measure = &measure_default_rules; 240 &ima_default_rules);
241 else {
242 int j = i - measure_entries;
243
244 list_add_tail(&default_appraise_rules[j].list,
245 &ima_default_rules);
246 }
247 }
248
249 ima_rules = &ima_default_rules;
215} 250}
216 251
217/** 252/**
@@ -228,8 +263,8 @@ void ima_update_policy(void)
228 int result = 1; 263 int result = 1;
229 int audit_info = 0; 264 int audit_info = 0;
230 265
231 if (ima_measure == &measure_default_rules) { 266 if (ima_rules == &ima_default_rules) {
232 ima_measure = &measure_policy_rules; 267 ima_rules = &ima_policy_rules;
233 cause = "complete"; 268 cause = "complete";
234 result = 0; 269 result = 0;
235 } 270 }
@@ -240,14 +275,17 @@ void ima_update_policy(void)
240enum { 275enum {
241 Opt_err = -1, 276 Opt_err = -1,
242 Opt_measure = 1, Opt_dont_measure, 277 Opt_measure = 1, Opt_dont_measure,
278 Opt_appraise, Opt_dont_appraise,
243 Opt_obj_user, Opt_obj_role, Opt_obj_type, 279 Opt_obj_user, Opt_obj_role, Opt_obj_type,
244 Opt_subj_user, Opt_subj_role, Opt_subj_type, 280 Opt_subj_user, Opt_subj_role, Opt_subj_type,
245 Opt_func, Opt_mask, Opt_fsmagic, Opt_uid 281 Opt_func, Opt_mask, Opt_fsmagic, Opt_uid, Opt_fowner
246}; 282};
247 283
248static match_table_t policy_tokens = { 284static match_table_t policy_tokens = {
249 {Opt_measure, "measure"}, 285 {Opt_measure, "measure"},
250 {Opt_dont_measure, "dont_measure"}, 286 {Opt_dont_measure, "dont_measure"},
287 {Opt_appraise, "appraise"},
288 {Opt_dont_appraise, "dont_appraise"},
251 {Opt_obj_user, "obj_user=%s"}, 289 {Opt_obj_user, "obj_user=%s"},
252 {Opt_obj_role, "obj_role=%s"}, 290 {Opt_obj_role, "obj_role=%s"},
253 {Opt_obj_type, "obj_type=%s"}, 291 {Opt_obj_type, "obj_type=%s"},
@@ -258,10 +296,11 @@ static match_table_t policy_tokens = {
258 {Opt_mask, "mask=%s"}, 296 {Opt_mask, "mask=%s"},
259 {Opt_fsmagic, "fsmagic=%s"}, 297 {Opt_fsmagic, "fsmagic=%s"},
260 {Opt_uid, "uid=%s"}, 298 {Opt_uid, "uid=%s"},
299 {Opt_fowner, "fowner=%s"},
261 {Opt_err, NULL} 300 {Opt_err, NULL}
262}; 301};
263 302
264static int ima_lsm_rule_init(struct ima_measure_rule_entry *entry, 303static int ima_lsm_rule_init(struct ima_rule_entry *entry,
265 char *args, int lsm_rule, int audit_type) 304 char *args, int lsm_rule, int audit_type)
266{ 305{
267 int result; 306 int result;
@@ -285,7 +324,7 @@ static void ima_log_string(struct audit_buffer *ab, char *key, char *value)
285 audit_log_format(ab, " "); 324 audit_log_format(ab, " ");
286} 325}
287 326
288static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry) 327static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
289{ 328{
290 struct audit_buffer *ab; 329 struct audit_buffer *ab;
291 char *p; 330 char *p;
@@ -294,6 +333,7 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
294 ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_INTEGRITY_RULE); 333 ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_INTEGRITY_RULE);
295 334
296 entry->uid = -1; 335 entry->uid = -1;
336 entry->fowner = -1;
297 entry->action = UNKNOWN; 337 entry->action = UNKNOWN;
298 while ((p = strsep(&rule, " \t")) != NULL) { 338 while ((p = strsep(&rule, " \t")) != NULL) {
299 substring_t args[MAX_OPT_ARGS]; 339 substring_t args[MAX_OPT_ARGS];
@@ -322,11 +362,27 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
322 362
323 entry->action = DONT_MEASURE; 363 entry->action = DONT_MEASURE;
324 break; 364 break;
365 case Opt_appraise:
366 ima_log_string(ab, "action", "appraise");
367
368 if (entry->action != UNKNOWN)
369 result = -EINVAL;
370
371 entry->action = APPRAISE;
372 break;
373 case Opt_dont_appraise:
374 ima_log_string(ab, "action", "dont_appraise");
375
376 if (entry->action != UNKNOWN)
377 result = -EINVAL;
378
379 entry->action = DONT_APPRAISE;
380 break;
325 case Opt_func: 381 case Opt_func:
326 ima_log_string(ab, "func", args[0].from); 382 ima_log_string(ab, "func", args[0].from);
327 383
328 if (entry->func) 384 if (entry->func)
329 result = -EINVAL; 385 result = -EINVAL;
330 386
331 if (strcmp(args[0].from, "FILE_CHECK") == 0) 387 if (strcmp(args[0].from, "FILE_CHECK") == 0)
332 entry->func = FILE_CHECK; 388 entry->func = FILE_CHECK;
@@ -391,6 +447,23 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
391 entry->flags |= IMA_UID; 447 entry->flags |= IMA_UID;
392 } 448 }
393 break; 449 break;
450 case Opt_fowner:
451 ima_log_string(ab, "fowner", args[0].from);
452
453 if (entry->fowner != -1) {
454 result = -EINVAL;
455 break;
456 }
457
458 result = strict_strtoul(args[0].from, 10, &lnum);
459 if (!result) {
460 entry->fowner = (uid_t) lnum;
461 if (entry->fowner != lnum)
462 result = -EINVAL;
463 else
464 entry->flags |= IMA_FOWNER;
465 }
466 break;
394 case Opt_obj_user: 467 case Opt_obj_user:
395 ima_log_string(ab, "obj_user", args[0].from); 468 ima_log_string(ab, "obj_user", args[0].from);
396 result = ima_lsm_rule_init(entry, args[0].from, 469 result = ima_lsm_rule_init(entry, args[0].from,
@@ -442,7 +515,7 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
442} 515}
443 516
444/** 517/**
445 * ima_parse_add_rule - add a rule to measure_policy_rules 518 * ima_parse_add_rule - add a rule to ima_policy_rules
446 * @rule - ima measurement policy rule 519 * @rule - ima measurement policy rule
447 * 520 *
448 * Uses a mutex to protect the policy list from multiple concurrent writers. 521 * Uses a mutex to protect the policy list from multiple concurrent writers.
@@ -452,12 +525,12 @@ ssize_t ima_parse_add_rule(char *rule)
452{ 525{
453 const char *op = "update_policy"; 526 const char *op = "update_policy";
454 char *p; 527 char *p;
455 struct ima_measure_rule_entry *entry; 528 struct ima_rule_entry *entry;
456 ssize_t result, len; 529 ssize_t result, len;
457 int audit_info = 0; 530 int audit_info = 0;
458 531
459 /* Prevent installed policy from changing */ 532 /* Prevent installed policy from changing */
460 if (ima_measure != &measure_default_rules) { 533 if (ima_rules != &ima_default_rules) {
461 integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, 534 integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL,
462 NULL, op, "already exists", 535 NULL, op, "already exists",
463 -EACCES, audit_info); 536 -EACCES, audit_info);
@@ -490,9 +563,9 @@ ssize_t ima_parse_add_rule(char *rule)
490 return result; 563 return result;
491 } 564 }
492 565
493 mutex_lock(&ima_measure_mutex); 566 mutex_lock(&ima_rules_mutex);
494 list_add_tail(&entry->list, &measure_policy_rules); 567 list_add_tail(&entry->list, &ima_policy_rules);
495 mutex_unlock(&ima_measure_mutex); 568 mutex_unlock(&ima_rules_mutex);
496 569
497 return len; 570 return len;
498} 571}
@@ -500,12 +573,12 @@ ssize_t ima_parse_add_rule(char *rule)
500/* ima_delete_rules called to cleanup invalid policy */ 573/* ima_delete_rules called to cleanup invalid policy */
501void ima_delete_rules(void) 574void ima_delete_rules(void)
502{ 575{
503 struct ima_measure_rule_entry *entry, *tmp; 576 struct ima_rule_entry *entry, *tmp;
504 577
505 mutex_lock(&ima_measure_mutex); 578 mutex_lock(&ima_rules_mutex);
506 list_for_each_entry_safe(entry, tmp, &measure_policy_rules, list) { 579 list_for_each_entry_safe(entry, tmp, &ima_policy_rules, list) {
507 list_del(&entry->list); 580 list_del(&entry->list);
508 kfree(entry); 581 kfree(entry);
509 } 582 }
510 mutex_unlock(&ima_measure_mutex); 583 mutex_unlock(&ima_rules_mutex);
511} 584}