selinux: Implement the new mount API LSM hooks
authorDavid Howells <dhowells@redhat.com>
Thu, 1 Nov 2018 23:07:24 +0000 (23:07 +0000)
committerAl Viro <viro@zeniv.linux.org.uk>
Thu, 28 Feb 2019 08:29:24 +0000 (03:29 -0500)
Implement the new mount API LSM hooks for SELinux.  At some point the old
hooks will need to be removed.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Paul Moore <paul@paul-moore.com>
cc: Stephen Smalley <sds@tycho.nsa.gov>
cc: selinux@tycho.nsa.gov
cc: linux-security-module@vger.kernel.org
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
security/selinux/hooks.c
security/selinux/include/security.h

index f0e36c3..f99381e 100644 (file)
@@ -48,6 +48,8 @@
 #include <linux/fdtable.h>
 #include <linux/namei.h>
 #include <linux/mount.h>
+#include <linux/fs_context.h>
+#include <linux/fs_parser.h>
 #include <linux/netfilter_ipv4.h>
 #include <linux/netfilter_ipv6.h>
 #include <linux/tty.h>
@@ -454,11 +456,11 @@ static inline int inode_doinit(struct inode *inode)
 
 enum {
        Opt_error = -1,
-       Opt_context = 1,
+       Opt_context = 0,
+       Opt_defcontext = 1,
        Opt_fscontext = 2,
-       Opt_defcontext = 3,
-       Opt_rootcontext = 4,
-       Opt_seclabel = 5,
+       Opt_rootcontext = 3,
+       Opt_seclabel = 4,
 };
 
 #define A(s, has_arg) {#s, sizeof(#s) - 1, Opt_##s, has_arg}
@@ -1089,6 +1091,7 @@ static int show_sid(struct seq_file *m, u32 sid)
        if (!rc) {
                bool has_comma = context && strchr(context, ',');
 
+               seq_putc(m, '=');
                if (has_comma)
                        seq_putc(m, '\"');
                seq_escape(m, context, "\"\n\\");
@@ -1142,7 +1145,7 @@ static int selinux_sb_show_options(struct seq_file *m, struct super_block *sb)
        }
        if (sbsec->flags & SBLABEL_MNT) {
                seq_putc(m, ',');
-               seq_puts(m, LABELSUPP_STR);
+               seq_puts(m, SECLABEL_STR);
        }
        return 0;
 }
@@ -2761,6 +2764,38 @@ static int selinux_umount(struct vfsmount *mnt, int flags)
                                   FILESYSTEM__UNMOUNT, NULL);
 }
 
+static const struct fs_parameter_spec selinux_param_specs[] = {
+       fsparam_string(CONTEXT_STR,     Opt_context),
+       fsparam_string(DEFCONTEXT_STR,  Opt_defcontext),
+       fsparam_string(FSCONTEXT_STR,   Opt_fscontext),
+       fsparam_string(ROOTCONTEXT_STR, Opt_rootcontext),
+       fsparam_flag  (SECLABEL_STR,    Opt_seclabel),
+       {}
+};
+
+static const struct fs_parameter_description selinux_fs_parameters = {
+       .name           = "SELinux",
+       .specs          = selinux_param_specs,
+};
+
+static int selinux_fs_context_parse_param(struct fs_context *fc,
+                                         struct fs_parameter *param)
+{
+       struct fs_parse_result result;
+       int opt, rc;
+
+       opt = fs_parse(fc, &selinux_fs_parameters, param, &result);
+       if (opt < 0)
+               return opt;
+
+       rc = selinux_add_opt(opt, param->string, &fc->security);
+       if (!rc) {
+               param->string = NULL;
+               rc = 1;
+       }
+       return rc;
+}
+
 /* inode security operations */
 
 static int selinux_inode_alloc_security(struct inode *inode)
@@ -6710,6 +6745,8 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
        LSM_HOOK_INIT(bprm_committing_creds, selinux_bprm_committing_creds),
        LSM_HOOK_INIT(bprm_committed_creds, selinux_bprm_committed_creds),
 
+       LSM_HOOK_INIT(fs_context_parse_param, selinux_fs_context_parse_param),
+
        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),
@@ -6978,6 +7015,8 @@ static __init int selinux_init(void)
        else
                pr_debug("SELinux:  Starting in permissive mode\n");
 
+       fs_validate_description(&selinux_fs_parameters);
+
        return 0;
 }
 
index ba8eedf..529d894 100644 (file)
 #define SE_SBPROC              0x0200
 #define SE_SBGENFS             0x0400
 
-#define CONTEXT_STR    "context="
-#define FSCONTEXT_STR  "fscontext="
-#define ROOTCONTEXT_STR        "rootcontext="
-#define DEFCONTEXT_STR "defcontext="
-#define LABELSUPP_STR "seclabel"
+#define CONTEXT_STR    "context"
+#define FSCONTEXT_STR  "fscontext"
+#define ROOTCONTEXT_STR        "rootcontext"
+#define DEFCONTEXT_STR "defcontext"
+#define SECLABEL_STR "seclabel"
 
 struct netlbl_lsm_secattr;