Smack: freeing an error pointer in smk_write_revoke_subj()
authorDan Carpenter <dan.carpenter@oracle.com>
Thu, 11 Jun 2015 08:51:16 +0000 (11:51 +0300)
committerCasey Schaufler <casey@schaufler-ca.com>
Fri, 12 Jun 2015 18:59:11 +0000 (11:59 -0700)
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>
security/smack/smackfs.c

index f1c22a891b1afc038bddd9180cc8443acecf26b2..5e0a64ebdf237e2f0fd1e3cb4db93c8e3d2eda37 100644 (file)
@@ -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;
 }