same issue as with selinux... [fix by Andrei Vagin folded in]
Unified · Split
| @@ -59,14 +59,31 @@ static LIST_HEAD(smk_ipv6_port_list); · 58 unmodified lines | ||
| 59 | 59 | static struct kmem_cache *smack_inode_cache; |
| 60 | 60 | int smack_enabled; |
| 61 | 61 | |
| 62 | −static const match_table_t smk_mount_tokens = { | |
| 63 | − {Opt_fsdefault, SMK_FSDEFAULT "%s"}, | |
| 64 | − {Opt_fsfloor, SMK_FSFLOOR "%s"}, | |
| 65 | − {Opt_fshat, SMK_FSHAT "%s"}, | |
| 66 | − {Opt_fsroot, SMK_FSROOT "%s"}, | |
| 67 | − {Opt_fstransmute, SMK_FSTRANS "%s"}, | |
| 68 | − {Opt_error, NULL}, | |
| 62 | +#define A(s) {"smack"#s, sizeof("smack"#s) - 1, Opt_##s} | |
| 63 | +static struct { | |
| 64 | + const char *name; | |
| 65 | + int len; | |
| 66 | + int opt; | |
| 67 | +} smk_mount_opts[] = { | |
| 68 | + A(fsdefault), A(fsfloor), A(fshat), A(fsroot), A(fstransmute) | |
| 69 | 69 | }; |
| 70 | +#undef A | |
| 71 | + | |
| 72 | +static int match_opt_prefix(char *s, int l, char **arg) | |
| 73 | +{ | |
| 74 | + int i; | |
| 75 | + | |
| 76 | + for (i = 0; i < ARRAY_SIZE(smk_mount_opts); i++) { | |
| 77 | + size_t len = smk_mount_opts[i].len; | |
| 78 | + if (len > l || memcmp(s, smk_mount_opts[i].name, len)) | |
| 79 | + continue; | |
| 80 | + if (len == l || s[len] != '=') | |
| 81 | + continue; | |
| 82 | + *arg = s + len + 1; | |
| 83 | + return smk_mount_opts[i].opt; | |
| 84 | + } | |
| 85 | + return Opt_error; | |
| 86 | +} | |
| 70 | 87 | |
| 71 | 88 | #ifdef CONFIG_SECURITY_SMACK_BRINGUP |
| 72 | 89 | static char *smk_bu_mess[] = { |
| @@ -689,23 +706,23 @@ out_opt_err: · 616 unmodified lines | ||
| 689 | 706 | static int smack_parse_opts_str(char *options, |
| 690 | 707 | void **mnt_opts) |
| 691 | 708 | { |
| 692 | − char *p; | |
| 693 | − int rc = -ENOMEM; | |
| 694 | − int token; | |
| 709 | + char *from = options; | |
| 695 | 710 | |
| 696 | 711 | if (!options) |
| 697 | 712 | return 0; |
| 698 | 713 | |
| 699 | − while ((p = strsep(&options, ",")) != NULL) { | |
| 700 | − substring_t args[MAX_OPT_ARGS]; | |
| 701 | − const char *arg; | |
| 702 | − | |
| 703 | − if (!*p) | |
| 704 | − continue; | |
| 714 | + while (1) { | |
| 715 | + char *next = strchr(from, ','); | |
| 716 | + int token, len, rc; | |
| 717 | + char *arg = NULL; | |
| 705 | 718 | |
| 706 | − token = match_token(p, smk_mount_tokens, args); | |
| 719 | + if (next) | |
| 720 | + len = next - from; | |
| 721 | + else | |
| 722 | + len = strlen(from); | |
| 707 | 723 | |
| 708 | − arg = match_strdup(&args[0]); | |
| 724 | + token = match_opt_prefix(from, len, &arg); | |
| 725 | + arg = kmemdup_nul(arg, from + len - arg, GFP_KERNEL); | |
| 709 | 726 | rc = smack_add_opt(token, arg, mnt_opts); |
| 710 | 727 | if (unlikely(rc)) { |
| 711 | 728 | kfree(arg); |
| @@ -714,6 +731,9 @@ static int smack_parse_opts_str(char *options, · 2 unmodified lines | ||
| 714 | 731 | *mnt_opts = NULL; |
| 715 | 732 | return rc; |
| 716 | 733 | } |
| 734 | + if (!from[len]) | |
| 735 | + break; | |
| 736 | + from += len + 1; | |
| 717 | 737 | } |
| 718 | 738 | return 0; |
| 719 | 739 | } |