smack: take the guts of smack_parse_opts_str() into a new helper

smack_add_opt() adds an already matched option to growing smack_mnt_options

Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Al Viro 2018-12-16 01:09:45 -05:00
parent 757cbe597f
commit 55c0e5bd07
1 changed files with 57 additions and 57 deletions

View File

@ -629,6 +629,54 @@ static int smack_sb_copy_data(char *orig, char *smackopts)
return 0; return 0;
} }
static int smack_add_opt(int token, const char *s, void **mnt_opts)
{
struct smack_mnt_opts *opts = *mnt_opts;
if (!opts) {
opts = kzalloc(sizeof(struct smack_mnt_opts), GFP_KERNEL);
if (!opts)
return -ENOMEM;
*mnt_opts = opts;
}
if (!s)
return -ENOMEM;
switch (token) {
case Opt_fsdefault:
if (opts->fsdefault)
goto out_opt_err;
opts->fsdefault = s;
break;
case Opt_fsfloor:
if (opts->fsfloor)
goto out_opt_err;
opts->fsfloor = s;
break;
case Opt_fshat:
if (opts->fshat)
goto out_opt_err;
opts->fshat = s;
break;
case Opt_fsroot:
if (opts->fsroot)
goto out_opt_err;
opts->fsroot = s;
break;
case Opt_fstransmute:
if (opts->fstransmute)
goto out_opt_err;
opts->fstransmute = s;
break;
}
return 0;
out_opt_err:
pr_warn("Smack: duplicate mount options\n");
return -EINVAL;
}
/** /**
* smack_parse_opts_str - parse Smack specific mount options * smack_parse_opts_str - parse Smack specific mount options
* @options: mount options string * @options: mount options string
@ -641,7 +689,6 @@ static int smack_sb_copy_data(char *orig, char *smackopts)
static int smack_parse_opts_str(char *options, static int smack_parse_opts_str(char *options,
void **mnt_opts) void **mnt_opts)
{ {
struct smack_mnt_opts *opts = *mnt_opts;
char *p; char *p;
int rc = -ENOMEM; int rc = -ENOMEM;
int token; int token;
@ -651,71 +698,24 @@ static int smack_parse_opts_str(char *options,
while ((p = strsep(&options, ",")) != NULL) { while ((p = strsep(&options, ",")) != NULL) {
substring_t args[MAX_OPT_ARGS]; substring_t args[MAX_OPT_ARGS];
const char *arg;
if (!*p) if (!*p)
continue; continue;
token = match_token(p, smk_mount_tokens, args); token = match_token(p, smk_mount_tokens, args);
if (!opts) { arg = match_strdup(&args[0]);
opts = kzalloc(sizeof(struct smack_mnt_opts), GFP_KERNEL); rc = smack_add_opt(token, arg, mnt_opts);
if (!opts) if (unlikely(rc)) {
return -ENOMEM; kfree(arg);
} if (*mnt_opts)
smack_free_mnt_opts(*mnt_opts);
switch (token) { *mnt_opts = NULL;
case Opt_fsdefault: return rc;
if (opts->fsdefault)
goto out_opt_err;
opts->fsdefault = match_strdup(&args[0]);
if (!opts->fsdefault)
goto out_err;
break;
case Opt_fsfloor:
if (opts->fsfloor)
goto out_opt_err;
opts->fsfloor = match_strdup(&args[0]);
if (!opts->fsfloor)
goto out_err;
break;
case Opt_fshat:
if (opts->fshat)
goto out_opt_err;
opts->fshat = match_strdup(&args[0]);
if (!opts->fshat)
goto out_err;
break;
case Opt_fsroot:
if (opts->fsroot)
goto out_opt_err;
opts->fsroot = match_strdup(&args[0]);
if (!opts->fsroot)
goto out_err;
break;
case Opt_fstransmute:
if (opts->fstransmute)
goto out_opt_err;
opts->fstransmute = match_strdup(&args[0]);
if (!opts->fstransmute)
goto out_err;
break;
default:
rc = -EINVAL;
pr_warn("Smack: unknown mount option\n");
goto out_err;
} }
} }
*mnt_opts = opts;
return 0; return 0;
out_opt_err:
rc = -EINVAL;
pr_warn("Smack: duplicate mount options\n");
out_err:
if (opts)
smack_free_mnt_opts(opts);
return rc;
} }
static int smack_sb_eat_lsm_opts(char *options, void **mnt_opts) static int smack_sb_eat_lsm_opts(char *options, void **mnt_opts)