diff options
author | Tomasz Stanislawski <t.stanislaws@samsung.com> | 2013-06-06 03:30:50 -0400 |
---|---|---|
committer | Casey Schaufler <casey@schaufler-ca.com> | 2013-08-01 15:57:24 -0400 |
commit | 470043ba995a79a274a5db306856975002a06f19 (patch) | |
tree | 4c10363d8e9d4d8e8d8f33fa00fce7632ead3b17 /security | |
parent | be0306bcc3a0b0725b0f99b06d56a29a6d906b7c (diff) |
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>
Diffstat (limited to 'security')
-rw-r--r-- | security/smack/smackfs.c | 33 |
1 files changed, 11 insertions, 22 deletions
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index ab167037b2dd..269b270c6473 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c | |||
@@ -447,7 +447,7 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf, | |||
447 | struct list_head *rule_list, | 447 | struct list_head *rule_list, |
448 | struct mutex *rule_lock, int format) | 448 | struct mutex *rule_lock, int format) |
449 | { | 449 | { |
450 | struct smack_parsed_rule *rule; | 450 | struct smack_parsed_rule rule; |
451 | char *data; | 451 | char *data; |
452 | int datalen; | 452 | int datalen; |
453 | int rc = -EINVAL; | 453 | int rc = -EINVAL; |
@@ -479,47 +479,36 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf, | |||
479 | goto out; | 479 | goto out; |
480 | } | 480 | } |
481 | 481 | ||
482 | rule = kzalloc(sizeof(*rule), GFP_KERNEL); | ||
483 | if (rule == NULL) { | ||
484 | rc = -ENOMEM; | ||
485 | goto out; | ||
486 | } | ||
487 | |||
488 | if (format == SMK_LONG_FMT) { | 482 | if (format == SMK_LONG_FMT) { |
489 | /* | 483 | /* |
490 | * Be sure the data string is terminated. | 484 | * Be sure the data string is terminated. |
491 | */ | 485 | */ |
492 | data[count] = '\0'; | 486 | data[count] = '\0'; |
493 | if (smk_parse_long_rule(data, rule, 1, 0)) | 487 | if (smk_parse_long_rule(data, &rule, 1, 0)) |
494 | goto out_free_rule; | 488 | goto out; |
495 | } else if (format == SMK_CHANGE_FMT) { | 489 | } else if (format == SMK_CHANGE_FMT) { |
496 | data[count] = '\0'; | 490 | data[count] = '\0'; |
497 | if (smk_parse_long_rule(data, rule, 1, 1)) | 491 | if (smk_parse_long_rule(data, &rule, 1, 1)) |
498 | goto out_free_rule; | 492 | goto out; |
499 | } else { | 493 | } else { |
500 | /* | 494 | /* |
501 | * More on the minor hack for backward compatibility | 495 | * More on the minor hack for backward compatibility |
502 | */ | 496 | */ |
503 | if (count == (SMK_OLOADLEN)) | 497 | if (count == (SMK_OLOADLEN)) |
504 | data[SMK_OLOADLEN] = '-'; | 498 | data[SMK_OLOADLEN] = '-'; |
505 | if (smk_parse_rule(data, rule, 1)) | 499 | if (smk_parse_rule(data, &rule, 1)) |
506 | goto out_free_rule; | 500 | goto out; |
507 | } | 501 | } |
508 | 502 | ||
509 | if (rule_list == NULL) { | 503 | if (rule_list == NULL) { |
510 | load = 1; | 504 | load = 1; |
511 | rule_list = &rule->smk_subject->smk_rules; | 505 | rule_list = &rule.smk_subject->smk_rules; |
512 | rule_lock = &rule->smk_subject->smk_rules_lock; | 506 | rule_lock = &rule.smk_subject->smk_rules_lock; |
513 | } | 507 | } |
514 | 508 | ||
515 | rc = smk_set_access(rule, rule_list, rule_lock, load); | 509 | rc = smk_set_access(&rule, rule_list, rule_lock, load); |
516 | if (rc == 0) { | 510 | if (rc == 0) |
517 | rc = count; | 511 | rc = count; |
518 | goto out; | ||
519 | } | ||
520 | |||
521 | out_free_rule: | ||
522 | kfree(rule); | ||
523 | out: | 512 | out: |
524 | kfree(data); | 513 | kfree(data); |
525 | return rc; | 514 | return rc; |