summaryrefslogtreecommitdiff
path: root/security/smack
diff options
context:
space:
mode:
authorCasey Schaufler <casey@schaufler-ca.com>2023-04-05 08:46:14 -0700
committerCasey Schaufler <casey@schaufler-ca.com>2023-04-05 08:46:14 -0700
commitde93e515db306767549bb29a926f523ca2a601ab (patch)
tree1740d612aa0754b21cb142eae1e4cf47ca043111 /security/smack
parent502a29b04d857c28aa36f8829a5c673b9b8864a6 (diff)
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: Casey Schaufler <casey@schaufler-ca.com>
Diffstat (limited to 'security/smack')
-rw-r--r--security/smack/smack_lsm.c62
1 files changed, 23 insertions, 39 deletions
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 24ade96e17b3..027f6e2a3a27 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -550,23 +550,22 @@ static int smack_sb_alloc_security(struct super_block *sb)
}
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)
{
- struct smack_mnt_opts *opts = mnt_opts;
- kfree(opts->fsdefault);
- kfree(opts->fsfloor);
- kfree(opts->fshat);
- kfree(opts->fsroot);
- kfree(opts->fstransmute);
- kfree(opts);
+ kfree(mnt_opts);
}
static int smack_add_opt(int token, const char *s, void **mnt_opts)
{
struct smack_mnt_opts *opts = *mnt_opts;
+ struct smack_known *skp;
if (!opts) {
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)
if (!s)
return -ENOMEM;
+ skp = smk_import_entry(s, 0);
+ if (IS_ERR(skp))
+ return PTR_ERR(skp);
+
switch (token) {
case Opt_fsdefault:
if (opts->fsdefault)
goto out_opt_err;
- opts->fsdefault = s;
+ opts->fsdefault = skp->smk_known;
break;
case Opt_fsfloor:
if (opts->fsfloor)
goto out_opt_err;
- opts->fsfloor = s;
+ opts->fsfloor = skp->smk_known;
break;
case Opt_fshat:
if (opts->fshat)
goto out_opt_err;
- opts->fshat = s;
+ opts->fshat = skp->smk_known;
break;
case Opt_fsroot:
if (opts->fsroot)
goto out_opt_err;
- opts->fsroot = s;
+ opts->fsroot = skp->smk_known;
break;
case Opt_fstransmute:
if (opts->fstransmute)
goto out_opt_err;
- opts->fstransmute = s;
+ opts->fstransmute = skp->smk_known;
break;
}
return 0;
@@ -629,33 +632,14 @@ static int smack_fs_context_dup(struct fs_context *fc,
fc->security = kzalloc(sizeof(struct smack_mnt_opts), GFP_KERNEL);
if (!fc->security)
return -ENOMEM;
+
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;
}
@@ -712,8 +696,8 @@ static int smack_sb_eat_lsm_opts(char *options, void **mnt_opts)
if (token != Opt_error) {
arg = kmemdup_nul(arg, from + len - arg, GFP_KERNEL);
rc = smack_add_opt(token, arg, mnt_opts);
+ kfree(arg);
if (unlikely(rc)) {
- kfree(arg);
if (*mnt_opts)
smack_free_mnt_opts(*mnt_opts);
*mnt_opts = NULL;