diff options
| author | Dan Carpenter <dan.carpenter@oracle.com> | 2015-06-11 04:51:16 -0400 |
|---|---|---|
| committer | Casey Schaufler <casey@schaufler-ca.com> | 2015-06-12 14:59:11 -0400 |
| commit | 5430209497eeb01415c681aaac0d00f65d24a526 (patch) | |
| tree | 88bb712ff5231e78e43f9d7a4c63f2bf2d1f8be2 /security/smack | |
| parent | c0d77c884461fc0dec0411e49797dc3f3651c31b (diff) | |
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>
Diffstat (limited to 'security/smack')
| -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 = { | |||
| 2253 | static ssize_t smk_write_revoke_subj(struct file *file, const char __user *buf, | 2253 | static ssize_t smk_write_revoke_subj(struct file *file, const char __user *buf, |
| 2254 | size_t count, loff_t *ppos) | 2254 | size_t count, loff_t *ppos) |
| 2255 | { | 2255 | { |
| 2256 | char *data = NULL; | 2256 | char *data; |
| 2257 | const char *cp = NULL; | 2257 | const char *cp; |
| 2258 | struct smack_known *skp; | 2258 | struct smack_known *skp; |
| 2259 | struct smack_rule *sp; | 2259 | struct smack_rule *sp; |
| 2260 | struct list_head *rule_list; | 2260 | struct list_head *rule_list; |
| @@ -2276,18 +2276,18 @@ static ssize_t smk_write_revoke_subj(struct file *file, const char __user *buf, | |||
| 2276 | 2276 | ||
| 2277 | if (copy_from_user(data, buf, count) != 0) { | 2277 | if (copy_from_user(data, buf, count) != 0) { |
| 2278 | rc = -EFAULT; | 2278 | rc = -EFAULT; |
| 2279 | goto free_out; | 2279 | goto out_data; |
| 2280 | } | 2280 | } |
| 2281 | 2281 | ||
| 2282 | cp = smk_parse_smack(data, count); | 2282 | cp = smk_parse_smack(data, count); |
| 2283 | if (IS_ERR(cp)) { | 2283 | if (IS_ERR(cp)) { |
| 2284 | rc = PTR_ERR(cp); | 2284 | rc = PTR_ERR(cp); |
| 2285 | goto free_out; | 2285 | goto out_data; |
| 2286 | } | 2286 | } |
| 2287 | 2287 | ||
| 2288 | skp = smk_find_entry(cp); | 2288 | skp = smk_find_entry(cp); |
| 2289 | if (skp == NULL) | 2289 | if (skp == NULL) |
| 2290 | goto free_out; | 2290 | goto out_cp; |
| 2291 | 2291 | ||
| 2292 | rule_list = &skp->smk_rules; | 2292 | rule_list = &skp->smk_rules; |
| 2293 | rule_lock = &skp->smk_rules_lock; | 2293 | rule_lock = &skp->smk_rules_lock; |
| @@ -2299,9 +2299,11 @@ static ssize_t smk_write_revoke_subj(struct file *file, const char __user *buf, | |||
| 2299 | 2299 | ||
| 2300 | mutex_unlock(rule_lock); | 2300 | mutex_unlock(rule_lock); |
| 2301 | 2301 | ||
| 2302 | free_out: | 2302 | out_cp: |
| 2303 | kfree(data); | ||
| 2304 | kfree(cp); | 2303 | kfree(cp); |
| 2304 | out_data: | ||
| 2305 | kfree(data); | ||
| 2306 | |||
| 2305 | return rc; | 2307 | return rc; |
| 2306 | } | 2308 | } |
| 2307 | 2309 | ||
