smack_add_opt() adds an already matched option to growing smack_mnt_options
Unified · Split
| @@ -629,6 +629,54 @@ static int smack_sb_copy_data(char *orig, char *smackopts) · 628 unmodified lines | ||
| 629 | 629 | return 0; |
| 630 | 630 | } |
| 631 | 631 | |
| 632 | +static int smack_add_opt(int token, const char *s, void **mnt_opts) | |
| 633 | +{ | |
| 634 | + struct smack_mnt_opts *opts = *mnt_opts; | |
| 635 | + | |
| 636 | + if (!opts) { | |
| 637 | + opts = kzalloc(sizeof(struct smack_mnt_opts), GFP_KERNEL); | |
| 638 | + if (!opts) | |
| 639 | + return -ENOMEM; | |
| 640 | + *mnt_opts = opts; | |
| 641 | + } | |
| 642 | + | |
| 643 | + if (!s) | |
| 644 | + return -ENOMEM; | |
| 645 | + | |
| 646 | + switch (token) { | |
| 647 | + case Opt_fsdefault: | |
| 648 | + if (opts->fsdefault) | |
| 649 | + goto out_opt_err; | |
| 650 | + opts->fsdefault = s; | |
| 651 | + break; | |
| 652 | + case Opt_fsfloor: | |
| 653 | + if (opts->fsfloor) | |
| 654 | + goto out_opt_err; | |
| 655 | + opts->fsfloor = s; | |
| 656 | + break; | |
| 657 | + case Opt_fshat: | |
| 658 | + if (opts->fshat) | |
| 659 | + goto out_opt_err; | |
| 660 | + opts->fshat = s; | |
| 661 | + break; | |
| 662 | + case Opt_fsroot: | |
| 663 | + if (opts->fsroot) | |
| 664 | + goto out_opt_err; | |
| 665 | + opts->fsroot = s; | |
| 666 | + break; | |
| 667 | + case Opt_fstransmute: | |
| 668 | + if (opts->fstransmute) | |
| 669 | + goto out_opt_err; | |
| 670 | + opts->fstransmute = s; | |
| 671 | + break; | |
| 672 | + } | |
| 673 | + return 0; | |
| 674 | + | |
| 675 | +out_opt_err: | |
| 676 | + pr_warn("Smack: duplicate mount options\n"); | |
| 677 | + return -EINVAL; | |
| 678 | +} | |
| 679 | + | |
| 632 | 680 | /** |
| 633 | 681 | * smack_parse_opts_str - parse Smack specific mount options |
| 634 | 682 | * @options: mount options string |
| @@ -641,7 +689,6 @@ static int smack_sb_copy_data(char *orig, char *smackopts) · 6 unmodified lines | ||
| 641 | 689 | static int smack_parse_opts_str(char *options, |
| 642 | 690 | void **mnt_opts) |
| 643 | 691 | { |
| 644 | − struct smack_mnt_opts *opts = *mnt_opts; | |
| 645 | 692 | char *p; |
| 646 | 693 | int rc = -ENOMEM; |
| 647 | 694 | int token; |
| @@ -651,71 +698,24 @@ static int smack_parse_opts_str(char *options, · 3 unmodified lines | ||
| 651 | 698 | |
| 652 | 699 | while ((p = strsep(&options, ",")) != NULL) { |
| 653 | 700 | substring_t args[MAX_OPT_ARGS]; |
| 701 | + const char *arg; | |
| 654 | 702 | |
| 655 | 703 | if (!*p) |
| 656 | 704 | continue; |
| 657 | 705 | |
| 658 | 706 | token = match_token(p, smk_mount_tokens, args); |
| 659 | 707 | |
| 660 | − if (!opts) { | |
| 661 | − opts = kzalloc(sizeof(struct smack_mnt_opts), GFP_KERNEL); | |
| 662 | − if (!opts) | |
| 663 | − return -ENOMEM; | |
| 664 | − } | |
| 665 | − | |
| 666 | − switch (token) { | |
| 667 | − case Opt_fsdefault: | |
| 668 | − if (opts->fsdefault) | |
| 669 | − goto out_opt_err; | |
| 670 | − opts->fsdefault = match_strdup(&args[0]); | |
| 671 | − if (!opts->fsdefault) | |
| 672 | − goto out_err; | |
| 673 | − break; | |
| 674 | − case Opt_fsfloor: | |
| 675 | − if (opts->fsfloor) | |
| 676 | − goto out_opt_err; | |
| 677 | − opts->fsfloor = match_strdup(&args[0]); | |
| 678 | − if (!opts->fsfloor) | |
| 679 | − goto out_err; | |
| 680 | − break; | |
| 681 | − case Opt_fshat: | |
| 682 | − if (opts->fshat) | |
| 683 | − goto out_opt_err; | |
| 684 | − opts->fshat = match_strdup(&args[0]); | |
| 685 | − if (!opts->fshat) | |
| 686 | − goto out_err; | |
| 687 | − break; | |
| 688 | − case Opt_fsroot: | |
| 689 | − if (opts->fsroot) | |
| 690 | − goto out_opt_err; | |
| 691 | − opts->fsroot = match_strdup(&args[0]); | |
| 692 | − if (!opts->fsroot) | |
| 693 | − goto out_err; | |
| 694 | − break; | |
| 695 | − case Opt_fstransmute: | |
| 696 | − if (opts->fstransmute) | |
| 697 | − goto out_opt_err; | |
| 698 | − opts->fstransmute = match_strdup(&args[0]); | |
| 699 | − if (!opts->fstransmute) | |
| 700 | − goto out_err; | |
| 701 | − break; | |
| 702 | − default: | |
| 703 | − rc = -EINVAL; | |
| 704 | − pr_warn("Smack: unknown mount option\n"); | |
| 705 | − goto out_err; | |
| 708 | + arg = match_strdup(&args[0]); | |
| 709 | + rc = smack_add_opt(token, arg, mnt_opts); | |
| 710 | + if (unlikely(rc)) { | |
| 711 | + kfree(arg); | |
| 712 | + if (*mnt_opts) | |
| 713 | + smack_free_mnt_opts(*mnt_opts); | |
| 714 | + *mnt_opts = NULL; | |
| 715 | + return rc; | |
| 706 | 716 | } |
| 707 | 717 | } |
| 708 | − *mnt_opts = opts; | |
| 709 | 718 | return 0; |
| 710 | − | |
| 711 | −out_opt_err: | |
| 712 | − rc = -EINVAL; | |
| 713 | − pr_warn("Smack: duplicate mount options\n"); | |
| 714 | − | |
| 715 | −out_err: | |
| 716 | − if (opts) | |
| 717 | − smack_free_mnt_opts(opts); | |
| 718 | − return rc; | |
| 719 | 719 | } |
| 720 | 720 | |
| 721 | 721 | static int smack_sb_eat_lsm_opts(char *options, void **mnt_opts) |