summary refs log tree commit diff
path: root/security/integrity
diff options
context:
space:
mode:
Diffstat (limited to 'security/integrity')
-rw-r--r--security/integrity/ima/ima.h2
-rw-r--r--security/integrity/ima/ima_fs.c38
-rw-r--r--security/integrity/ima/ima_policy.c18
3 files changed, 32 insertions, 26 deletions
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 47fb65d1fcbd..16d100d3fc38 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -135,7 +135,7 @@ enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK };
 int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask);
 void ima_init_policy(void);
 void ima_update_policy(void);
-int ima_parse_add_rule(char *);
+ssize_t ima_parse_add_rule(char *);
 void ima_delete_rules(void);
 
 /* LSM based policy rules require audit */
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index 0c72c9c38956..3674a52e1cfb 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -243,32 +243,34 @@ static const struct file_operations ima_ascii_measurements_ops = {
 static ssize_t ima_write_policy(struct file *file, const char __user *buf,
 				size_t datalen, loff_t *ppos)
 {
-	char *data;
-	int rc;
+	char *data = NULL;
+	ssize_t result;
 
 	if (datalen >= PAGE_SIZE)
-		return -ENOMEM;
-	if (*ppos != 0) {
-		/* No partial writes. */
-		return -EINVAL;
-	}
+		datalen = PAGE_SIZE - 1;
+
+	/* No partial writes. */
+	result = -EINVAL;
+	if (*ppos != 0)
+		goto out;
+
+	result = -ENOMEM;
 	data = kmalloc(datalen + 1, GFP_KERNEL);
 	if (!data)
-		return -ENOMEM;
+		goto out;
 
-	if (copy_from_user(data, buf, datalen)) {
-		kfree(data);
-		return -EFAULT;
-	}
 	*(data + datalen) = '\0';
-	rc = ima_parse_add_rule(data);
-	if (rc < 0) {
-		datalen = -EINVAL;
-		valid_policy = 0;
-	}
 
+	result = -EFAULT;
+	if (copy_from_user(data, buf, datalen))
+		goto out;
+
+	result = ima_parse_add_rule(data);
+out:
+	if (result < 0)
+		valid_policy = 0;
 	kfree(data);
-	return datalen;
+	return result;
 }
 
 static struct dentry *ima_dir;
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 4759d0f99335..49998f90e441 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -261,7 +261,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->action = -1;
-	while ((p = strsep(&rule, " \n")) != NULL) {
+	while ((p = strsep(&rule, " ")) != NULL) {
 		substring_t args[MAX_OPT_ARGS];
 		int token;
 		unsigned long lnum;
@@ -269,7 +269,7 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
 		if (result < 0)
 			break;
 		if (!*p)
-			continue;
+			break;
 		token = match_token(p, policy_tokens, args);
 		switch (token) {
 		case Opt_measure:
@@ -373,7 +373,7 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
 	if (entry->action == UNKNOWN)
 		result = -EINVAL;
 
-	audit_log_format(ab, "res=%d", !result ? 0 : 1);
+	audit_log_format(ab, "res=%d", !!result);
 	audit_log_end(ab);
 	return result;
 }
@@ -383,13 +383,14 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
  * @rule - ima measurement policy rule
  *
  * Uses a mutex to protect the policy list from multiple concurrent writers.
- * Returns 0 on success, an error code on failure.
+ * Returns the length of the rule parsed, an error code on failure
  */
-int ima_parse_add_rule(char *rule)
+ssize_t ima_parse_add_rule(char *rule)
 {
 	const char *op = "update_policy";
+	char *p;
 	struct ima_measure_rule_entry *entry;
-	int result = 0;
+	ssize_t result, len;
 	int audit_info = 0;
 
 	/* Prevent installed policy from changing */
@@ -409,8 +410,11 @@ int ima_parse_add_rule(char *rule)
 
 	INIT_LIST_HEAD(&entry->list);
 
-	result = ima_parse_rule(rule, entry);
+	p = strsep(&rule, "\n");
+	len = strlen(p) + 1;
+	result = ima_parse_rule(p, entry);
 	if (!result) {
+		result = len;
 		mutex_lock(&ima_measure_mutex);
 		list_add_tail(&entry->list, &measure_policy_rules);
 		mutex_unlock(&ima_measure_mutex);