aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAl Viro2018-12-13 15:18:05 -0500
committerAl Viro2018-12-21 11:48:54 -0500
commit12085b14a4440a6d12ff7966702c010df87caef0 (patch)
treed9c8192f4183f7f807f81953b685f041da1eb395
parentbd3236557bb256d6491df125e5e9d0393c70e4d2 (diff)
smack: switch to private smack_mnt_opts
Reviewed-by: David Howells <dhowells@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--security/smack/smack_lsm.c157
1 files changed, 55 insertions, 102 deletions
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 81a8112975d4..99aec9f42be3 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -567,16 +567,18 @@ static void smack_sb_free_security(struct super_block *sb)
sb->s_security = NULL;
}
+struct smack_mnt_opts {
+ const char *fsdefault, *fsfloor, *fshat, *fsroot, *fstransmute;
+};
+
static void smack_free_mnt_opts(void *mnt_opts)
{
- struct security_mnt_opts *opts = mnt_opts;
- int i;
-
- if (opts->mnt_opts)
- for (i = 0; i < opts->num_mnt_opts; i++)
- kfree(opts->mnt_opts[i]);
- kfree(opts->mnt_opts);
- kfree(opts->mnt_opts_flags);
+ struct smack_mnt_opts *opts = mnt_opts;
+ kfree(opts->fsdefault);
+ kfree(opts->fsfloor);
+ kfree(opts->fshat);
+ kfree(opts->fsroot);
+ kfree(opts->fstransmute);
kfree(opts);
}
@@ -639,28 +641,14 @@ static int smack_sb_copy_data(char *orig, char *smackopts)
static int smack_parse_opts_str(char *options,
void **mnt_opts)
{
- struct security_mnt_opts *opts = *mnt_opts;
+ struct smack_mnt_opts *opts = *mnt_opts;
char *p;
- char *fsdefault = NULL;
- char *fsfloor = NULL;
- char *fshat = NULL;
- char *fsroot = NULL;
- char *fstransmute = NULL;
int rc = -ENOMEM;
- int num_mnt_opts = 0;
int token;
if (!options)
return 0;
- if (!opts) {
- opts = kzalloc(sizeof(struct security_mnt_opts), GFP_KERNEL);
- *mnt_opts = opts;
- if (!opts)
- return -ENOMEM;
- }
- opts->num_mnt_opts = 0;
-
while ((p = strsep(&options, ",")) != NULL) {
substring_t args[MAX_OPT_ARGS];
@@ -669,40 +657,46 @@ static int smack_parse_opts_str(char *options,
token = match_token(p, smk_mount_tokens, args);
+ if (!opts) {
+ opts = kzalloc(sizeof(struct smack_mnt_opts), GFP_KERNEL);
+ if (!opts)
+ return -ENOMEM;
+ }
+
switch (token) {
case Opt_fsdefault:
- if (fsdefault)
+ if (opts->fsdefault)
goto out_opt_err;
- fsdefault = match_strdup(&args[0]);
- if (!fsdefault)
+ opts->fsdefault = match_strdup(&args[0]);
+ if (!opts->fsdefault)
goto out_err;
break;
case Opt_fsfloor:
- if (fsfloor)
+ if (opts->fsfloor)
goto out_opt_err;
- fsfloor = match_strdup(&args[0]);
- if (!fsfloor)
+ opts->fsfloor = match_strdup(&args[0]);
+ if (!opts->fsfloor)
goto out_err;
break;
case Opt_fshat:
- if (fshat)
+ if (opts->fshat)
goto out_opt_err;
- fshat = match_strdup(&args[0]);
- if (!fshat)
+ opts->fshat = match_strdup(&args[0]);
+ if (!opts->fshat)
goto out_err;
break;
case Opt_fsroot:
- if (fsroot)
+ if (opts->fsroot)
goto out_opt_err;
- fsroot = match_strdup(&args[0]);
- if (!fsroot)
+ opts->fsroot = match_strdup(&args[0]);
+ if (!opts->fsroot)
goto out_err;
break;
case Opt_fstransmute:
- if (fstransmute)
+ if (opts->fstransmute)
goto out_opt_err;
- fstransmute = match_strdup(&args[0]);
- if (!fstransmute)
+ opts->fstransmute = match_strdup(&args[0]);
+ if (!opts->fstransmute)
goto out_err;
break;
default:
@@ -711,38 +705,7 @@ static int smack_parse_opts_str(char *options,
goto out_err;
}
}
-
- opts->mnt_opts = kcalloc(NUM_SMK_MNT_OPTS, sizeof(char *), GFP_KERNEL);
- if (!opts->mnt_opts)
- goto out_err;
-
- opts->mnt_opts_flags = kcalloc(NUM_SMK_MNT_OPTS, sizeof(int),
- GFP_KERNEL);
- if (!opts->mnt_opts_flags)
- goto out_err;
-
- if (fsdefault) {
- opts->mnt_opts[num_mnt_opts] = fsdefault;
- opts->mnt_opts_flags[num_mnt_opts++] = FSDEFAULT_MNT;
- }
- if (fsfloor) {
- opts->mnt_opts[num_mnt_opts] = fsfloor;
- opts->mnt_opts_flags[num_mnt_opts++] = FSFLOOR_MNT;
- }
- if (fshat) {
- opts->mnt_opts[num_mnt_opts] = fshat;
- opts->mnt_opts_flags[num_mnt_opts++] = FSHAT_MNT;
- }
- if (fsroot) {
- opts->mnt_opts[num_mnt_opts] = fsroot;
- opts->mnt_opts_flags[num_mnt_opts++] = FSROOT_MNT;
- }
- if (fstransmute) {
- opts->mnt_opts[num_mnt_opts] = fstransmute;
- opts->mnt_opts_flags[num_mnt_opts++] = FSTRANS_MNT;
- }
-
- opts->num_mnt_opts = num_mnt_opts;
+ *mnt_opts = opts;
return 0;
out_opt_err:
@@ -750,12 +713,8 @@ out_opt_err:
pr_warn("Smack: duplicate mount options\n");
out_err:
- kfree(fsdefault);
- kfree(fsfloor);
- kfree(fshat);
- kfree(fsroot);
- kfree(fstransmute);
- security_free_mnt_opts(mnt_opts);
+ if (opts)
+ smack_free_mnt_opts(opts);
return rc;
}
@@ -795,10 +754,8 @@ static int smack_set_mnt_opts(struct super_block *sb,
struct superblock_smack *sp = sb->s_security;
struct inode_smack *isp;
struct smack_known *skp;
- int i;
- struct security_mnt_opts *opts = mnt_opts;
- int num_opts = opts ? opts->num_mnt_opts : 0;
- int transmute = 0;
+ struct smack_mnt_opts *opts = mnt_opts;
+ bool transmute = false;
if (sp->smk_flags & SMK_SB_INITIALIZED)
return 0;
@@ -807,7 +764,7 @@ static int smack_set_mnt_opts(struct super_block *sb,
/*
* Unprivileged mounts don't get to specify Smack values.
*/
- if (num_opts)
+ if (opts)
return -EPERM;
/*
* Unprivileged mounts get root and default from the caller.
@@ -823,48 +780,44 @@ static int smack_set_mnt_opts(struct super_block *sb,
if (sb->s_user_ns != &init_user_ns &&
sb->s_magic != SYSFS_MAGIC && sb->s_magic != TMPFS_MAGIC &&
sb->s_magic != RAMFS_MAGIC) {
- transmute = 1;
+ transmute = true;
sp->smk_flags |= SMK_SB_UNTRUSTED;
}
}
sp->smk_flags |= SMK_SB_INITIALIZED;
- for (i = 0; i < num_opts; i++) {
- switch (opts->mnt_opts_flags[i]) {
- case FSDEFAULT_MNT:
- skp = smk_import_entry(opts->mnt_opts[i], 0);
+ if (opts) {
+ if (opts->fsdefault) {
+ skp = smk_import_entry(opts->fsdefault, 0);
if (IS_ERR(skp))
return PTR_ERR(skp);
sp->smk_default = skp;
- break;
- case FSFLOOR_MNT:
- skp = smk_import_entry(opts->mnt_opts[i], 0);
+ }
+ if (opts->fsfloor) {
+ skp = smk_import_entry(opts->fsfloor, 0);
if (IS_ERR(skp))
return PTR_ERR(skp);
sp->smk_floor = skp;
- break;
- case FSHAT_MNT:
- skp = smk_import_entry(opts->mnt_opts[i], 0);
+ }
+ if (opts->fshat) {
+ skp = smk_import_entry(opts->fshat, 0);
if (IS_ERR(skp))
return PTR_ERR(skp);
sp->smk_hat = skp;
- break;
- case FSROOT_MNT:
- skp = smk_import_entry(opts->mnt_opts[i], 0);
+ }
+ if (opts->fsroot) {
+ skp = smk_import_entry(opts->fsroot, 0);
if (IS_ERR(skp))
return PTR_ERR(skp);
sp->smk_root = skp;
- break;
- case FSTRANS_MNT:
- skp = smk_import_entry(opts->mnt_opts[i], 0);
+ }
+ if (opts->fstransmute) {
+ skp = smk_import_entry(opts->fstransmute, 0);
if (IS_ERR(skp))
return PTR_ERR(skp);
sp->smk_root = skp;
- transmute = 1;
- break;
- default:
- break;
+ transmute = true;
}
}