aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/super.c10
-rw-r--r--fs/namespace.c9
-rw-r--r--fs/nfs/internal.h2
-rw-r--r--fs/nfs/super.c6
-rw-r--r--fs/super.c12
-rw-r--r--include/linux/lsm_hooks.h11
-rw-r--r--include/linux/security.h43
-rw-r--r--security/security.c27
-rw-r--r--security/selinux/hooks.c52
-rw-r--r--security/smack/smack_lsm.c38
10 files changed, 118 insertions, 92 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 3b04e7735b5f..e90c4616ed6a 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -1472,14 +1472,13 @@ static struct dentry *btrfs_mount_root(struct file_system_type *fs_type,
struct btrfs_device *device = NULL;
struct btrfs_fs_devices *fs_devices = NULL;
struct btrfs_fs_info *fs_info = NULL;
- struct security_mnt_opts new_sec_opts;
+ void *new_sec_opts = NULL;
fmode_t mode = FMODE_READ;
int error = 0;
if (!(flags & SB_RDONLY))
mode |= FMODE_WRITE;
- security_init_mnt_opts(&new_sec_opts);
if (data) {
error = security_sb_eat_lsm_opts(data, &new_sec_opts);
if (error)
@@ -1551,7 +1550,7 @@ static struct dentry *btrfs_mount_root(struct file_system_type *fs_type,
error = btrfs_fill_super(s, fs_devices, data);
}
if (!error)
- error = security_sb_set_mnt_opts(s, &new_sec_opts, 0, NULL);
+ error = security_sb_set_mnt_opts(s, new_sec_opts, 0, NULL);
security_free_mnt_opts(&new_sec_opts);
if (error) {
deactivate_locked_super(s);
@@ -1724,12 +1723,11 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
btrfs_remount_prepare(fs_info);
if (data) {
- struct security_mnt_opts new_sec_opts;
+ void *new_sec_opts = NULL;
- security_init_mnt_opts(&new_sec_opts);
ret = security_sb_eat_lsm_opts(data, &new_sec_opts);
if (!ret)
- ret = security_sb_remount(sb, &new_sec_opts);
+ ret = security_sb_remount(sb, new_sec_opts);
security_free_mnt_opts(&new_sec_opts);
if (ret)
goto restore;
diff --git a/fs/namespace.c b/fs/namespace.c
index 39aca7b69c2e..badfd287358c 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2299,7 +2299,7 @@ static int do_remount(struct path *path, int ms_flags, int sb_flags,
int err;
struct super_block *sb = path->mnt->mnt_sb;
struct mount *mnt = real_mount(path->mnt);
- struct security_mnt_opts opts;
+ void *sec_opts = NULL;
if (!check_mnt(mnt))
return -EINVAL;
@@ -2310,14 +2310,13 @@ static int do_remount(struct path *path, int ms_flags, int sb_flags,
if (!can_change_locked_flags(mnt, mnt_flags))
return -EPERM;
- security_init_mnt_opts(&opts);
if (data && !(sb->s_type->fs_flags & FS_BINARY_MOUNTDATA)) {
- err = security_sb_eat_lsm_opts(data, &opts);
+ err = security_sb_eat_lsm_opts(data, &sec_opts);
if (err)
return err;
}
- err = security_sb_remount(sb, &opts);
- security_free_mnt_opts(&opts);
+ err = security_sb_remount(sb, sec_opts);
+ security_free_mnt_opts(&sec_opts);
if (err)
return err;
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 8357ff69962f..97e1dcefe561 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -123,7 +123,7 @@ struct nfs_parsed_mount_data {
unsigned short protocol;
} nfs_server;
- struct security_mnt_opts lsm_opts;
+ void *lsm_opts;
struct net *net;
};
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 300bdd1d4a09..1943de8f9d29 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -929,7 +929,7 @@ static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(void)
data->minorversion = 0;
data->need_mount = true;
data->net = current->nsproxy->net_ns;
- security_init_mnt_opts(&data->lsm_opts);
+ data->lsm_opts = NULL;
}
return data;
}
@@ -2294,7 +2294,7 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data)
/* compare new mount options with old ones */
error = nfs_compare_remount_data(nfss, data);
if (!error)
- error = security_sb_remount(sb, &data->lsm_opts);
+ error = security_sb_remount(sb, data->lsm_opts);
out:
nfs_free_parsed_mount_data(data);
return error;
@@ -2534,7 +2534,7 @@ int nfs_set_sb_security(struct super_block *s, struct dentry *mntroot,
if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL)
kflags |= SECURITY_LSM_NATIVE_LABELS;
- error = security_sb_set_mnt_opts(s, &mount_info->parsed->lsm_opts,
+ error = security_sb_set_mnt_opts(s, mount_info->parsed->lsm_opts,
kflags, &kflags_out);
if (error)
goto err;
diff --git a/fs/super.c b/fs/super.c
index 1f75fe312597..a5511c4ba69b 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -1247,12 +1247,10 @@ mount_fs(struct file_system_type *type, int flags, const char *name, void *data)
struct dentry *root;
struct super_block *sb;
int error = -ENOMEM;
- struct security_mnt_opts opts;
-
- security_init_mnt_opts(&opts);
+ void *sec_opts = NULL;
if (data && !(type->fs_flags & FS_BINARY_MOUNTDATA)) {
- error = security_sb_eat_lsm_opts(data, &opts);
+ error = security_sb_eat_lsm_opts(data, &sec_opts);
if (error)
return ERR_PTR(error);
}
@@ -1275,7 +1273,7 @@ mount_fs(struct file_system_type *type, int flags, const char *name, void *data)
smp_wmb();
sb->s_flags |= SB_BORN;
- error = security_sb_set_mnt_opts(sb, &opts, 0, NULL);
+ error = security_sb_set_mnt_opts(sb, sec_opts, 0, NULL);
if (error)
goto out_sb;
@@ -1295,13 +1293,13 @@ mount_fs(struct file_system_type *type, int flags, const char *name, void *data)
"negative value (%lld)\n", type->name, sb->s_maxbytes);
up_write(&sb->s_umount);
- security_free_mnt_opts(&opts);
+ security_free_mnt_opts(&sec_opts);
return root;
out_sb:
dput(root);
deactivate_locked_super(sb);
out_free_secdata:
- security_free_mnt_opts(&opts);
+ security_free_mnt_opts(&sec_opts);
return ERR_PTR(error);
}
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index c418909c178c..a9c541f5732e 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -1461,9 +1461,9 @@ union security_list_options {
int (*sb_alloc_security)(struct super_block *sb);
void (*sb_free_security)(struct super_block *sb);
- int (*sb_eat_lsm_opts)(char *orig, struct security_mnt_opts *opts);
- int (*sb_remount)(struct super_block *sb,
- struct security_mnt_opts *opts);
+ void (*sb_free_mnt_opts)(void *mnt_opts);
+ int (*sb_eat_lsm_opts)(char *orig, void **mnt_opts);
+ int (*sb_remount)(struct super_block *sb, void *mnt_opts);
int (*sb_kern_mount)(struct super_block *sb);
int (*sb_show_options)(struct seq_file *m, struct super_block *sb);
int (*sb_statfs)(struct dentry *dentry);
@@ -1472,14 +1472,14 @@ union security_list_options {
int (*sb_umount)(struct vfsmount *mnt, int flags);
int (*sb_pivotroot)(const struct path *old_path, const struct path *new_path);
int (*sb_set_mnt_opts)(struct super_block *sb,
- struct security_mnt_opts *opts,
+ void *mnt_opts,
unsigned long kern_flags,
unsigned long *set_kern_flags);
int (*sb_clone_mnt_opts)(const struct super_block *oldsb,
struct super_block *newsb,
unsigned long kern_flags,
unsigned long *set_kern_flags);
- int (*sb_parse_opts_str)(char *options, struct security_mnt_opts *opts);
+ int (*sb_parse_opts_str)(char *options, void **mnt_opts);
int (*dentry_init_security)(struct dentry *dentry, int mode,
const struct qstr *name, void **ctx,
u32 *ctxlen);
@@ -1801,6 +1801,7 @@ struct security_hook_heads {
struct hlist_head bprm_committed_creds;
struct hlist_head sb_alloc_security;
struct hlist_head sb_free_security;
+ struct hlist_head sb_free_mnt_opts;
struct hlist_head sb_eat_lsm_opts;
struct hlist_head sb_remount;
struct hlist_head sb_kern_mount;
diff --git a/include/linux/security.h b/include/linux/security.h
index d00093363570..4bca0be95b7a 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -192,26 +192,6 @@ int call_lsm_notifier(enum lsm_event event, void *data);
int register_lsm_notifier(struct notifier_block *nb);
int unregister_lsm_notifier(struct notifier_block *nb);
-static inline void security_init_mnt_opts(struct security_mnt_opts *opts)
-{
- opts->mnt_opts = NULL;
- opts->mnt_opts_flags = NULL;
- opts->num_mnt_opts = 0;
-}
-
-static inline void security_free_mnt_opts(struct security_mnt_opts *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);
- opts->mnt_opts = NULL;
- kfree(opts->mnt_opts_flags);
- opts->mnt_opts_flags = NULL;
- opts->num_mnt_opts = 0;
-}
-
/* prototypes */
extern int security_init(void);
@@ -248,8 +228,9 @@ void security_bprm_committing_creds(struct linux_binprm *bprm);
void security_bprm_committed_creds(struct linux_binprm *bprm);
int security_sb_alloc(struct super_block *sb);
void security_sb_free(struct super_block *sb);
-int security_sb_eat_lsm_opts(char *options, struct security_mnt_opts *opts);
-int security_sb_remount(struct super_block *sb, struct security_mnt_opts *opts);
+void security_free_mnt_opts(void **mnt_opts);
+int security_sb_eat_lsm_opts(char *options, void **mnt_opts);
+int security_sb_remount(struct super_block *sb, void *mnt_opts);
int security_sb_kern_mount(struct super_block *sb);
int security_sb_show_options(struct seq_file *m, struct super_block *sb);
int security_sb_statfs(struct dentry *dentry);
@@ -258,14 +239,14 @@ int security_sb_mount(const char *dev_name, const struct path *path,
int security_sb_umount(struct vfsmount *mnt, int flags);
int security_sb_pivotroot(const struct path *old_path, const struct path *new_path);
int security_sb_set_mnt_opts(struct super_block *sb,
- struct security_mnt_opts *opts,
+ void *mnt_opts,
unsigned long kern_flags,
unsigned long *set_kern_flags);
int security_sb_clone_mnt_opts(const struct super_block *oldsb,
struct super_block *newsb,
unsigned long kern_flags,
unsigned long *set_kern_flags);
-int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts);
+int security_sb_parse_opts_str(char *options, void **mnt_opts);
int security_dentry_init_security(struct dentry *dentry, int mode,
const struct qstr *name, void **ctx,
u32 *ctxlen);
@@ -421,11 +402,7 @@ static inline int unregister_lsm_notifier(struct notifier_block *nb)
return 0;
}
-static inline void security_init_mnt_opts(struct security_mnt_opts *opts)
-{
-}
-
-static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
+static inline void security_free_mnt_opts(void **mnt_opts)
{
}
@@ -556,13 +533,13 @@ static inline void security_sb_free(struct super_block *sb)
{ }
static inline int security_sb_eat_lsm_opts(char *options,
- struct security_mnt_opts *opts)
+ void **mnt_opts)
{
return 0;
}
static inline int security_sb_remount(struct super_block *sb,
- struct security_mnt_opts *opts)
+ void *mnt_opts)
{
return 0;
}
@@ -602,7 +579,7 @@ static inline int security_sb_pivotroot(const struct path *old_path,
}
static inline int security_sb_set_mnt_opts(struct super_block *sb,
- struct security_mnt_opts *opts,
+ void *mnt_opts,
unsigned long kern_flags,
unsigned long *set_kern_flags)
{
@@ -617,7 +594,7 @@ static inline int security_sb_clone_mnt_opts(const struct super_block *oldsb,
return 0;
}
-static inline int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts)
+static inline int security_sb_parse_opts_str(char *options, void **mnt_opts)
{
return 0;
}
diff --git a/security/security.c b/security/security.c
index feb18c925349..b7a5a0051807 100644
--- a/security/security.c
+++ b/security/security.c
@@ -384,16 +384,25 @@ void security_sb_free(struct super_block *sb)
call_void_hook(sb_free_security, sb);
}
-int security_sb_eat_lsm_opts(char *options, struct security_mnt_opts *opts)
+void security_free_mnt_opts(void **mnt_opts)
{
- return call_int_hook(sb_eat_lsm_opts, 0, options, opts);
+ if (!*mnt_opts)
+ return;
+ call_void_hook(sb_free_mnt_opts, *mnt_opts);
+ *mnt_opts = NULL;
+}
+EXPORT_SYMBOL(security_free_mnt_opts);
+
+int security_sb_eat_lsm_opts(char *options, void **mnt_opts)
+{
+ return call_int_hook(sb_eat_lsm_opts, 0, options, mnt_opts);
}
EXPORT_SYMBOL(security_sb_eat_lsm_opts);
int security_sb_remount(struct super_block *sb,
- struct security_mnt_opts *opts)
+ void *mnt_opts)
{
- return call_int_hook(sb_remount, 0, sb, opts);
+ return call_int_hook(sb_remount, 0, sb, mnt_opts);
}
EXPORT_SYMBOL(security_sb_remount);
@@ -429,13 +438,13 @@ int security_sb_pivotroot(const struct path *old_path, const struct path *new_pa
}
int security_sb_set_mnt_opts(struct super_block *sb,
- struct security_mnt_opts *opts,
+ void *mnt_opts,
unsigned long kern_flags,
unsigned long *set_kern_flags)
{
return call_int_hook(sb_set_mnt_opts,
- opts->num_mnt_opts ? -EOPNOTSUPP : 0, sb,
- opts, kern_flags, set_kern_flags);
+ mnt_opts ? -EOPNOTSUPP : 0, sb,
+ mnt_opts, kern_flags, set_kern_flags);
}
EXPORT_SYMBOL(security_sb_set_mnt_opts);
@@ -449,9 +458,9 @@ int security_sb_clone_mnt_opts(const struct super_block *oldsb,
}
EXPORT_SYMBOL(security_sb_clone_mnt_opts);
-int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts)
+int security_sb_parse_opts_str(char *options, void **mnt_opts)
{
- return call_int_hook(sb_parse_opts_str, 0, options, opts);
+ return call_int_hook(sb_parse_opts_str, 0, options, mnt_opts);
}
EXPORT_SYMBOL(security_sb_parse_opts_str);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 11cf2feb27b3..caf7ca7abfc1 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -433,6 +433,19 @@ static void superblock_free_security(struct super_block *sb)
kfree(sbsec);
}
+static void selinux_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);
+ kfree(opts);
+}
+
static inline int inode_doinit(struct inode *inode)
{
return inode_doinit_with_dentry(inode, NULL);
@@ -616,7 +629,7 @@ static int bad_option(struct superblock_security_struct *sbsec, char flag,
* labeling information.
*/
static int selinux_set_mnt_opts(struct super_block *sb,
- struct security_mnt_opts *opts,
+ void *mnt_opts,
unsigned long kern_flags,
unsigned long *set_kern_flags)
{
@@ -628,9 +641,10 @@ static int selinux_set_mnt_opts(struct super_block *sb,
struct inode_security_struct *root_isec;
u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0;
u32 defcontext_sid = 0;
- char **mount_options = opts->mnt_opts;
- int *flags = opts->mnt_opts_flags;
- int num_opts = opts->num_mnt_opts;
+ struct security_mnt_opts *opts = mnt_opts;
+ char **mount_options = opts ? opts->mnt_opts : NULL;
+ int *flags = opts ? opts->mnt_opts_flags : NULL;
+ int num_opts = opts ? opts->num_mnt_opts : 0;
mutex_lock(&sbsec->lock);
@@ -982,12 +996,20 @@ out:
}
static int selinux_parse_opts_str(char *options,
- struct security_mnt_opts *opts)
+ void **mnt_opts)
{
char *p;
char *context = NULL, *defcontext = NULL;
char *fscontext = NULL, *rootcontext = NULL;
int rc, num_mnt_opts = 0;
+ struct security_mnt_opts *opts = *mnt_opts;
+
+ if (!opts) {
+ opts = kzalloc(sizeof(struct security_mnt_opts), GFP_KERNEL);
+ *mnt_opts = opts;
+ if (!opts)
+ return -ENOMEM;
+ }
opts->num_mnt_opts = 0;
@@ -1094,7 +1116,7 @@ static int selinux_parse_opts_str(char *options,
return 0;
out_err:
- security_free_mnt_opts(opts);
+ security_free_mnt_opts(mnt_opts);
kfree(context);
kfree(defcontext);
kfree(fscontext);
@@ -2714,7 +2736,7 @@ out:
return rc;
}
-static int selinux_sb_eat_lsm_opts(char *options, struct security_mnt_opts *opts)
+static int selinux_sb_eat_lsm_opts(char *options, void **mnt_opts)
{
char *s = (char *)get_zeroed_page(GFP_KERNEL);
int err;
@@ -2723,14 +2745,14 @@ static int selinux_sb_eat_lsm_opts(char *options, struct security_mnt_opts *opts
return -ENOMEM;
err = selinux_sb_copy_data(options, s);
if (!err)
- err = selinux_parse_opts_str(s, opts);
+ err = selinux_parse_opts_str(s, mnt_opts);
free_page((unsigned long)s);
return err;
}
-static int selinux_sb_remount(struct super_block *sb,
- struct security_mnt_opts *opts)
+static int selinux_sb_remount(struct super_block *sb, void *mnt_opts)
{
+ struct security_mnt_opts *opts = mnt_opts;
int i, *flags;
char **mount_options;
struct superblock_security_struct *sbsec = sb->s_security;
@@ -2738,6 +2760,9 @@ static int selinux_sb_remount(struct super_block *sb,
if (!(sbsec->flags & SE_SBINITIALIZED))
return 0;
+ if (!opts)
+ return 0;
+
mount_options = opts->mnt_opts;
flags = opts->mnt_opts_flags;
@@ -6782,6 +6807,7 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
LSM_HOOK_INIT(sb_alloc_security, selinux_sb_alloc_security),
LSM_HOOK_INIT(sb_free_security, selinux_sb_free_security),
LSM_HOOK_INIT(sb_eat_lsm_opts, selinux_sb_eat_lsm_opts),
+ LSM_HOOK_INIT(sb_free_mnt_opts, selinux_free_mnt_opts),
LSM_HOOK_INIT(sb_remount, selinux_sb_remount),
LSM_HOOK_INIT(sb_kern_mount, selinux_sb_kern_mount),
LSM_HOOK_INIT(sb_show_options, selinux_sb_show_options),
@@ -7051,11 +7077,7 @@ static __init int selinux_init(void)
static void delayed_superblock_init(struct super_block *sb, void *unused)
{
- struct security_mnt_opts opts;
-
- security_init_mnt_opts(&opts);
- selinux_set_mnt_opts(sb, &opts, 0, NULL);
- security_free_mnt_opts(&opts);
+ selinux_set_mnt_opts(sb, NULL, 0, NULL);
}
void selinux_complete_init(void)
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 835cca277c2a..81a8112975d4 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -567,6 +567,19 @@ static void smack_sb_free_security(struct super_block *sb)
sb->s_security = NULL;
}
+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);
+ kfree(opts);
+}
+
/**
* smack_sb_copy_data - copy mount options data for processing
* @orig: where to start
@@ -624,8 +637,9 @@ static int smack_sb_copy_data(char *orig, char *smackopts)
* converts Smack specific mount options to generic security option format
*/
static int smack_parse_opts_str(char *options,
- struct security_mnt_opts *opts)
+ void **mnt_opts)
{
+ struct security_mnt_opts *opts = *mnt_opts;
char *p;
char *fsdefault = NULL;
char *fsfloor = NULL;
@@ -636,11 +650,17 @@ static int smack_parse_opts_str(char *options,
int num_mnt_opts = 0;
int token;
- opts->num_mnt_opts = 0;
-
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];
@@ -735,11 +755,11 @@ out_err:
kfree(fshat);
kfree(fsroot);
kfree(fstransmute);
- security_free_mnt_opts(opts);
+ security_free_mnt_opts(mnt_opts);
return rc;
}
-static int smack_sb_eat_lsm_opts(char *options, struct security_mnt_opts *opts)
+static int smack_sb_eat_lsm_opts(char *options, void **mnt_opts)
{
char *s = (char *)get_zeroed_page(GFP_KERNEL);
int err;
@@ -748,7 +768,7 @@ static int smack_sb_eat_lsm_opts(char *options, struct security_mnt_opts *opts)
return -ENOMEM;
err = smack_sb_copy_data(options, s);
if (!err)
- err = smack_parse_opts_str(s, opts);
+ err = smack_parse_opts_str(s, mnt_opts);
free_page((unsigned long)s);
return err;
}
@@ -766,7 +786,7 @@ static int smack_sb_eat_lsm_opts(char *options, struct security_mnt_opts *opts)
* labels.
*/
static int smack_set_mnt_opts(struct super_block *sb,
- struct security_mnt_opts *opts,
+ void *mnt_opts,
unsigned long kern_flags,
unsigned long *set_kern_flags)
{
@@ -776,7 +796,8 @@ static int smack_set_mnt_opts(struct super_block *sb,
struct inode_smack *isp;
struct smack_known *skp;
int i;
- int num_opts = opts->num_mnt_opts;
+ struct security_mnt_opts *opts = mnt_opts;
+ int num_opts = opts ? opts->num_mnt_opts : 0;
int transmute = 0;
if (sp->smk_flags & SMK_SB_INITIALIZED)
@@ -4651,6 +4672,7 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = {
LSM_HOOK_INIT(sb_alloc_security, smack_sb_alloc_security),
LSM_HOOK_INIT(sb_free_security, smack_sb_free_security),
+ LSM_HOOK_INIT(sb_free_mnt_opts, smack_free_mnt_opts),
LSM_HOOK_INIT(sb_eat_lsm_opts, smack_sb_eat_lsm_opts),
LSM_HOOK_INIT(sb_statfs, smack_sb_statfs),
LSM_HOOK_INIT(sb_set_mnt_opts, smack_set_mnt_opts),