summaryrefslogtreecommitdiffstats
path: root/security/integrity/ima/ima_policy.c
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2010-04-20 10:20:54 -0400
committerJames Morris <jmorris@namei.org>2010-04-21 09:58:13 +1000
commit6ccd045630054c99ba1bb35673db12cfcf1eea58 (patch)
treebce41e39722ae178807abe2213fd94e582842bae /security/integrity/ima/ima_policy.c
parenta200005038955057063fc8ea82129ebc785df41c (diff)
ima: handle multiple rules per write
Currently IMA will only accept one rule per write(). This patch allows IMA to accept writes which contain multiple rules but only processes one rule per write. \n is used as the delimiter between rules. IMA will return a short write indicating that it only accepted up to the first \n. This allows simple userspace utilities like cat to be used to load an IMA policy instead of needing a special userspace utility that understood 'one write per rule' 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/ima/ima_policy.c')
-rw-r--r--security/integrity/ima/ima_policy.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 4759d0f9933..49998f90e44 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);