diff options
author | Dan Carpenter <dan.carpenter@oracle.com> | 2015-06-11 11:51:16 +0300 |
---|---|---|
committer | Casey Schaufler <casey@schaufler-ca.com> | 2015-06-12 21:59:11 +0300 |
commit | 5430209497eeb01415c681aaac0d00f65d24a526 (patch) | |
tree | 88bb712ff5231e78e43f9d7a4c63f2bf2d1f8be2 | |
parent | c0d77c884461fc0dec0411e49797dc3f3651c31b (diff) | |
download | linux-5430209497eeb01415c681aaac0d00f65d24a526.tar.xz |
Smack: freeing an error pointer in smk_write_revoke_subj()
This code used to rely on the fact that kfree(NULL) was a no-op, but
then we changed smk_parse_smack() to return error pointers on failure
instead of NULL. Calling kfree() on an error pointer will oops.
I have re-arranged things a bit so that we only free things if they
have been allocated.
Fixes: e774ad683f42 ('smack: pass error code through pointers')
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
-rw-r--r-- | security/smack/smackfs.c | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index f1c22a891b1a..5e0a64ebdf23 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c @@ -2253,8 +2253,8 @@ static const struct file_operations smk_access2_ops = { static ssize_t smk_write_revoke_subj(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { - char *data = NULL; - const char *cp = NULL; + char *data; + const char *cp; struct smack_known *skp; struct smack_rule *sp; struct list_head *rule_list; @@ -2276,18 +2276,18 @@ static ssize_t smk_write_revoke_subj(struct file *file, const char __user *buf, if (copy_from_user(data, buf, count) != 0) { rc = -EFAULT; - goto free_out; + goto out_data; } cp = smk_parse_smack(data, count); if (IS_ERR(cp)) { rc = PTR_ERR(cp); - goto free_out; + goto out_data; } skp = smk_find_entry(cp); if (skp == NULL) - goto free_out; + goto out_cp; rule_list = &skp->smk_rules; rule_lock = &skp->smk_rules_lock; @@ -2299,9 +2299,11 @@ static ssize_t smk_write_revoke_subj(struct file *file, const char __user *buf, mutex_unlock(rule_lock); -free_out: - kfree(data); +out_cp: kfree(cp); +out_data: + kfree(data); + return rc; } |