Commit de93e515 authored by Casey Schaufler's avatar Casey Schaufler

Smack: Improve mount process memory use

The existing mount processing code in Smack makes many unnecessary
copies of Smack labels. Because Smack labels never go away once
imported it is safe to use pointers to them rather than copies.
Replace the use of copies of label names to pointers to the global
label list entries.
Signed-off-by: default avatarCasey Schaufler <casey@schaufler-ca.com>
parent 502a29b0
...@@ -550,23 +550,22 @@ static int smack_sb_alloc_security(struct super_block *sb) ...@@ -550,23 +550,22 @@ static int smack_sb_alloc_security(struct super_block *sb)
} }
struct smack_mnt_opts { struct smack_mnt_opts {
const char *fsdefault, *fsfloor, *fshat, *fsroot, *fstransmute; const char *fsdefault;
const char *fsfloor;
const char *fshat;
const char *fsroot;
const char *fstransmute;
}; };
static void smack_free_mnt_opts(void *mnt_opts) static void smack_free_mnt_opts(void *mnt_opts)
{ {
struct smack_mnt_opts *opts = mnt_opts; kfree(mnt_opts);
kfree(opts->fsdefault);
kfree(opts->fsfloor);
kfree(opts->fshat);
kfree(opts->fsroot);
kfree(opts->fstransmute);
kfree(opts);
} }
static int smack_add_opt(int token, const char *s, void **mnt_opts) static int smack_add_opt(int token, const char *s, void **mnt_opts)
{ {
struct smack_mnt_opts *opts = *mnt_opts; struct smack_mnt_opts *opts = *mnt_opts;
struct smack_known *skp;
if (!opts) { if (!opts) {
opts = kzalloc(sizeof(struct smack_mnt_opts), GFP_KERNEL); opts = kzalloc(sizeof(struct smack_mnt_opts), GFP_KERNEL);
...@@ -577,31 +576,35 @@ static int smack_add_opt(int token, const char *s, void **mnt_opts) ...@@ -577,31 +576,35 @@ static int smack_add_opt(int token, const char *s, void **mnt_opts)
if (!s) if (!s)
return -ENOMEM; return -ENOMEM;
skp = smk_import_entry(s, 0);
if (IS_ERR(skp))
return PTR_ERR(skp);
switch (token) { switch (token) {
case Opt_fsdefault: case Opt_fsdefault:
if (opts->fsdefault) if (opts->fsdefault)
goto out_opt_err; goto out_opt_err;
opts->fsdefault = s; opts->fsdefault = skp->smk_known;
break; break;
case Opt_fsfloor: case Opt_fsfloor:
if (opts->fsfloor) if (opts->fsfloor)
goto out_opt_err; goto out_opt_err;
opts->fsfloor = s; opts->fsfloor = skp->smk_known;
break; break;
case Opt_fshat: case Opt_fshat:
if (opts->fshat) if (opts->fshat)
goto out_opt_err; goto out_opt_err;
opts->fshat = s; opts->fshat = skp->smk_known;
break; break;
case Opt_fsroot: case Opt_fsroot:
if (opts->fsroot) if (opts->fsroot)
goto out_opt_err; goto out_opt_err;
opts->fsroot = s; opts->fsroot = skp->smk_known;
break; break;
case Opt_fstransmute: case Opt_fstransmute:
if (opts->fstransmute) if (opts->fstransmute)
goto out_opt_err; goto out_opt_err;
opts->fstransmute = s; opts->fstransmute = skp->smk_known;
break; break;
} }
return 0; return 0;
...@@ -629,33 +632,14 @@ static int smack_fs_context_dup(struct fs_context *fc, ...@@ -629,33 +632,14 @@ static int smack_fs_context_dup(struct fs_context *fc,
fc->security = kzalloc(sizeof(struct smack_mnt_opts), GFP_KERNEL); fc->security = kzalloc(sizeof(struct smack_mnt_opts), GFP_KERNEL);
if (!fc->security) if (!fc->security)
return -ENOMEM; return -ENOMEM;
dst = fc->security; dst = fc->security;
dst->fsdefault = src->fsdefault;
dst->fsfloor = src->fsfloor;
dst->fshat = src->fshat;
dst->fsroot = src->fsroot;
dst->fstransmute = src->fstransmute;
if (src->fsdefault) {
dst->fsdefault = kstrdup(src->fsdefault, GFP_KERNEL);
if (!dst->fsdefault)
return -ENOMEM;
}
if (src->fsfloor) {
dst->fsfloor = kstrdup(src->fsfloor, GFP_KERNEL);
if (!dst->fsfloor)
return -ENOMEM;
}
if (src->fshat) {
dst->fshat = kstrdup(src->fshat, GFP_KERNEL);
if (!dst->fshat)
return -ENOMEM;
}
if (src->fsroot) {
dst->fsroot = kstrdup(src->fsroot, GFP_KERNEL);
if (!dst->fsroot)
return -ENOMEM;
}
if (src->fstransmute) {
dst->fstransmute = kstrdup(src->fstransmute, GFP_KERNEL);
if (!dst->fstransmute)
return -ENOMEM;
}
return 0; return 0;
} }
...@@ -712,8 +696,8 @@ static int smack_sb_eat_lsm_opts(char *options, void **mnt_opts) ...@@ -712,8 +696,8 @@ static int smack_sb_eat_lsm_opts(char *options, void **mnt_opts)
if (token != Opt_error) { if (token != Opt_error) {
arg = kmemdup_nul(arg, from + len - arg, GFP_KERNEL); arg = kmemdup_nul(arg, from + len - arg, GFP_KERNEL);
rc = smack_add_opt(token, arg, mnt_opts); rc = smack_add_opt(token, arg, mnt_opts);
kfree(arg);
if (unlikely(rc)) { if (unlikely(rc)) {
kfree(arg);
if (*mnt_opts) if (*mnt_opts)
smack_free_mnt_opts(*mnt_opts); smack_free_mnt_opts(*mnt_opts);
*mnt_opts = NULL; *mnt_opts = NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment