summaryrefslogtreecommitdiffstats
path: root/security/integrity
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2010-04-20 16:21:01 +0200
committerJames Morris <jmorris@namei.org>2010-04-21 01:58:14 +0200
commit7b62e162129c3b28d51016774e0c7c57c710c452 (patch)
treec6d18b649b70bb684b2a648a4a00956f2d1e62e2 /security/integrity
parentima: handle multiple rules per write (diff)
downloadlinux-7b62e162129c3b28d51016774e0c7c57c710c452.tar.xz
linux-7b62e162129c3b28d51016774e0c7c57c710c452.zip
IMA: do not allow the same rule to specify the same thing twice
IMA will accept rules which specify things twice and will only pay attention to the last one. We should reject such rules. Signed-off-by: Eric Paris <eparis@redhat.com> Acked-by: Mimi Zohar <zohar@us.ibm.com> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/integrity')
-rw-r--r--security/integrity/ima/ima_policy.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 49998f90e441..c771a2036691 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -245,6 +245,9 @@ static int ima_lsm_rule_init(struct ima_measure_rule_entry *entry,
{
int result;
+ if (entry->lsm[lsm_rule].rule)
+ return -EINVAL;
+
entry->lsm[lsm_rule].type = audit_type;
result = security_filter_rule_init(entry->lsm[lsm_rule].type,
Audit_equal, args,
@@ -260,6 +263,7 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_INTEGRITY_RULE);
+ entry->uid = -1;
entry->action = -1;
while ((p = strsep(&rule, " ")) != NULL) {
substring_t args[MAX_OPT_ARGS];
@@ -274,14 +278,26 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
switch (token) {
case Opt_measure:
audit_log_format(ab, "%s ", "measure");
+
+ if (entry->action != UNKNOWN)
+ result = -EINVAL;
+
entry->action = MEASURE;
break;
case Opt_dont_measure:
audit_log_format(ab, "%s ", "dont_measure");
+
+ if (entry->action != UNKNOWN)
+ result = -EINVAL;
+
entry->action = DONT_MEASURE;
break;
case Opt_func:
audit_log_format(ab, "func=%s ", args[0].from);
+
+ if (entry->func)
+ result = -EINVAL;
+
if (strcmp(args[0].from, "FILE_CHECK") == 0)
entry->func = FILE_CHECK;
/* PATH_CHECK is for backwards compat */
@@ -298,6 +314,10 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
break;
case Opt_mask:
audit_log_format(ab, "mask=%s ", args[0].from);
+
+ if (entry->mask)
+ result = -EINVAL;
+
if ((strcmp(args[0].from, "MAY_EXEC")) == 0)
entry->mask = MAY_EXEC;
else if (strcmp(args[0].from, "MAY_WRITE") == 0)
@@ -313,6 +333,12 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
break;
case Opt_fsmagic:
audit_log_format(ab, "fsmagic=%s ", args[0].from);
+
+ if (entry->fsmagic) {
+ result = -EINVAL;
+ break;
+ }
+
result = strict_strtoul(args[0].from, 16,
&entry->fsmagic);
if (!result)
@@ -320,6 +346,12 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
break;
case Opt_uid:
audit_log_format(ab, "uid=%s ", args[0].from);
+
+ if (entry->uid != -1) {
+ result = -EINVAL;
+ break;
+ }
+
result = strict_strtoul(args[0].from, 10, &lnum);
if (!result) {
entry->uid = (uid_t) lnum;
@@ -370,7 +402,7 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
break;
}
}
- if (entry->action == UNKNOWN)
+ if (!result && (entry->action == UNKNOWN))
result = -EINVAL;
audit_log_format(ab, "res=%d", !!result);