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 | return 0; | 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 | * smack_parse_opts_str - parse Smack specific mount options | 681 | * smack_parse_opts_str - parse Smack specific mount options |
| 634 | * @options: mount options string | 682 | * @options: mount options string |
| @@ -641,7 +689,6 @@ static int smack_sb_copy_data(char *orig, char *smackopts) · 6 unmodified lines | |||
| 641 | static int smack_parse_opts_str(char *options, | 689 | static int smack_parse_opts_str(char *options, |
| 642 | void **mnt_opts) | 690 | void **mnt_opts) |
| 643 | { | 691 | { |
| 644 | struct smack_mnt_opts *opts = *mnt_opts; | ||
| 645 | char *p; | 692 | char *p; |
| 646 | int rc = -ENOMEM; | 693 | int rc = -ENOMEM; |
| 647 | int token; | 694 | int token; |
| @@ -651,71 +698,24 @@ static int smack_parse_opts_str(char *options, · 3 unmodified lines | |||
| 651 | 698 | ||
| 652 | while ((p = strsep(&options, ",")) != NULL) { | 699 | while ((p = strsep(&options, ",")) != NULL) { |
| 653 | substring_t args[MAX_OPT_ARGS]; | 700 | substring_t args[MAX_OPT_ARGS]; |
| 701 | const char *arg; | ||
| 654 | 702 | ||
| 655 | if (!*p) | 703 | if (!*p) |
| 656 | continue; | 704 | continue; |
| 657 | 705 | ||
| 658 | token = match_token(p, smk_mount_tokens, args); | 706 | token = match_token(p, smk_mount_tokens, args); |
| 659 | 707 | ||
| 660 | if (!opts) { | 708 | arg = match_strdup(&args[0]); |
| 661 | opts = kzalloc(sizeof(struct smack_mnt_opts), GFP_KERNEL); | 709 | rc = smack_add_opt(token, arg, mnt_opts); |
| 662 | if (!opts) | 710 | if (unlikely(rc)) { |
| 663 | return -ENOMEM; | 711 | kfree(arg); |
| 664 | } | 712 | if (*mnt_opts) |
| 665 | 713 | smack_free_mnt_opts(*mnt_opts); | |
| 666 | switch (token) { | 714 | *mnt_opts = NULL; |
| 667 | case Opt_fsdefault: | 715 | return rc; |
| 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; | ||
| 706 | } | 716 | } |
| 707 | } | 717 | } |
| 708 | *mnt_opts = opts; | ||
| 709 | return 0; | 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 | static int smack_sb_eat_lsm_opts(char *options, void **mnt_opts) | 721 | static int smack_sb_eat_lsm_opts(char *options, void **mnt_opts) |