security: smack: fix memleak in smk_write_rules_list()

The smack_parsed_rule structure is allocated.  If a rule is successfully
installed then the last reference to the object is lost.  This patch fixes this
leak. Moreover smack_parsed_rule is allocated on stack because it no longer
needed ofter smk_write_rules_list() is finished.

Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com>
This commit is contained in:
Tomasz Stanislawski 2013-06-06 09:30:50 +02:00 committed by Casey Schaufler
parent be0306bcc3
commit 470043ba99
1 changed files with 11 additions and 22 deletions

View File

@ -447,7 +447,7 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
struct list_head *rule_list, struct list_head *rule_list,
struct mutex *rule_lock, int format) struct mutex *rule_lock, int format)
{ {
struct smack_parsed_rule *rule; struct smack_parsed_rule rule;
char *data; char *data;
int datalen; int datalen;
int rc = -EINVAL; int rc = -EINVAL;
@ -479,47 +479,36 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
goto out; goto out;
} }
rule = kzalloc(sizeof(*rule), GFP_KERNEL);
if (rule == NULL) {
rc = -ENOMEM;
goto out;
}
if (format == SMK_LONG_FMT) { if (format == SMK_LONG_FMT) {
/* /*
* Be sure the data string is terminated. * Be sure the data string is terminated.
*/ */
data[count] = '\0'; data[count] = '\0';
if (smk_parse_long_rule(data, rule, 1, 0)) if (smk_parse_long_rule(data, &rule, 1, 0))
goto out_free_rule; goto out;
} else if (format == SMK_CHANGE_FMT) { } else if (format == SMK_CHANGE_FMT) {
data[count] = '\0'; data[count] = '\0';
if (smk_parse_long_rule(data, rule, 1, 1)) if (smk_parse_long_rule(data, &rule, 1, 1))
goto out_free_rule; goto out;
} else { } else {
/* /*
* More on the minor hack for backward compatibility * More on the minor hack for backward compatibility
*/ */
if (count == (SMK_OLOADLEN)) if (count == (SMK_OLOADLEN))
data[SMK_OLOADLEN] = '-'; data[SMK_OLOADLEN] = '-';
if (smk_parse_rule(data, rule, 1)) if (smk_parse_rule(data, &rule, 1))
goto out_free_rule; goto out;
} }
if (rule_list == NULL) { if (rule_list == NULL) {
load = 1; load = 1;
rule_list = &rule->smk_subject->smk_rules; rule_list = &rule.smk_subject->smk_rules;
rule_lock = &rule->smk_subject->smk_rules_lock; rule_lock = &rule.smk_subject->smk_rules_lock;
} }
rc = smk_set_access(rule, rule_list, rule_lock, load); rc = smk_set_access(&rule, rule_list, rule_lock, load);
if (rc == 0) { if (rc == 0)
rc = count; rc = count;
goto out;
}
out_free_rule:
kfree(rule);
out: out:
kfree(data); kfree(data);
return rc; return rc;