]> git.proxmox.com Git - mirror_zfs.git/commitdiff
Add full SELinux support
authorMatthew Thode <mthode@mthode.org>
Thu, 19 Dec 2013 06:24:14 +0000 (00:24 -0600)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Thu, 19 Dec 2013 18:37:31 +0000 (10:37 -0800)
Four new dataset properties have been added to support SELinux.  They
are 'context', 'fscontext', 'defcontext' and 'rootcontext' which map
directly to the context options described in mount(8).  When one of
these properties is set to something other than 'none'.  That string
will be passed verbatim as a mount option for the given context when
the filesystem is mounted.

For example, if you wanted the rootcontext for a filesystem to be set
to 'system_u:object_r:fs_t' you would set the property as follows:

  $ zfs set rootcontext="system_u:object_r:fs_t" storage-pool/media

This will ensure the filesystem is automatically mounted with that
rootcontext.  It is equivalent to manually specifying the rootcontext
with the -o option like this:

  $ zfs mount -o rootcontext=system_u:object_r:fs_t storage-pool/media

By default all four contexts are set to 'none'.  Further information
on SELinux contexts is detailed in mount(8) and selinux(8) man pages.

Signed-off-by: Matthew Thode <prometheanfire@gentoo.org>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Richard Yao <ryao@gentoo.org>
Closes #1504

cmd/mount_zfs/Makefile.am
cmd/mount_zfs/mount_zfs.c
config/user-selinux.m4 [deleted file]
config/user.m4
include/sys/fs/zfs.h
lib/libspl/include/sys/mntent.h
man/man8/mount.zfs.8
man/man8/zfs.8
module/zcommon/zfs_prop.c
rpm/generic/zfs.spec.in

index fe34c96b761877e4db48de248e01e96d0913f9bb..e5f3d083b0a4f71a91d1202c423ebd1485379ef3 100644 (file)
@@ -20,5 +20,3 @@ mount_zfs_LDADD = \
        $(top_builddir)/lib/libzpool/libzpool.la \
        $(top_builddir)/lib/libzfs/libzfs.la \
        $(top_builddir)/lib/libzfs_core/libzfs_core.la
-
-mount_zfs_LDADD += $(LIBSELINUX)
index 82fa67c932d48f14e11fe0456b4e9b607efaaef0..6cb23d1c6d0a501c0fb5c0eb2dc151da82c668e8 100644 (file)
@@ -31,9 +31,6 @@
 #include <sys/stat.h>
 #include <libzfs.h>
 #include <locale.h>
-#ifdef HAVE_LIBSELINUX
-#include <selinux/selinux.h>
-#endif /* HAVE_LIBSELINUX */
 
 libzfs_handle_t *g_zfs;
 
@@ -77,11 +74,10 @@ static const option_map_t option_map[] = {
 #ifdef MS_STRICTATIME
        { MNTOPT_DFRATIME,      MS_STRICTATIME, ZS_COMMENT      },
 #endif
-       { MNTOPT_CONTEXT,       MS_COMMENT,     ZS_NOCONTEXT    },
-       { MNTOPT_NOCONTEXT,     MS_COMMENT,     ZS_NOCONTEXT    },
-       { MNTOPT_FSCONTEXT,     MS_COMMENT,     ZS_NOCONTEXT    },
-       { MNTOPT_DEFCONTEXT,    MS_COMMENT,     ZS_NOCONTEXT    },
-       { MNTOPT_ROOTCONTEXT,   MS_COMMENT,     ZS_NOCONTEXT    },
+       { MNTOPT_CONTEXT,       MS_COMMENT,     ZS_COMMENT      },
+       { MNTOPT_FSCONTEXT,     MS_COMMENT,     ZS_COMMENT      },
+       { MNTOPT_DEFCONTEXT,    MS_COMMENT,     ZS_COMMENT      },
+       { MNTOPT_ROOTCONTEXT,   MS_COMMENT,     ZS_COMMENT      },
 #ifdef MS_I_VERSION
        { MNTOPT_IVERSION,      MS_I_VERSION,   ZS_COMMENT      },
 #endif
@@ -338,11 +334,35 @@ mtab_update(char *dataset, char *mntpoint, char *type, char *mntopts)
        return (MOUNT_SUCCESS);
 }
 
+static void
+__zfs_selinux_setcontext(const char *name, const char *context, char *mntopts,
+    char *mtabopt)
+{
+       char tmp[MNT_LINE_MAX];
+
+       snprintf(tmp, MNT_LINE_MAX, ",%s=\"%s\"", name, context);
+       strlcat(mntopts, tmp, MNT_LINE_MAX);
+       strlcat(mtabopt, tmp, MNT_LINE_MAX);
+}
+
+static void
+zfs_selinux_setcontext(zfs_handle_t *zhp, zfs_prop_t zpt, const char *name,
+    char *mntopts, char *mtabopt)
+{
+       char context[ZFS_MAXPROPLEN];
+
+       if (zfs_prop_get(zhp, zpt, context, sizeof (context),
+           NULL, NULL, 0, B_FALSE) == 0) {
+               if (strcmp(context, "none") != 0)
+                   __zfs_selinux_setcontext(name, context, mntopts, mtabopt);
+       }
+}
+
 int
 main(int argc, char **argv)
 {
        zfs_handle_t *zhp;
-       char legacy[ZFS_MAXPROPLEN];
+       char prop[ZFS_MAXPROPLEN];
        char mntopts[MNT_LINE_MAX] = { '\0' };
        char badopt[MNT_LINE_MAX] = { '\0' };
        char mtabopt[MNT_LINE_MAX] = { '\0' };
@@ -437,22 +457,6 @@ main(int argc, char **argv)
                }
        }
 
-#ifdef HAVE_LIBSELINUX
-       /*
-        * Automatically add the default zfs context when selinux is enabled
-        * and the caller has not specified their own context.  This must be
-        * done until zfs is added to the default selinux policy configuration
-        * as a known filesystem type which supports xattrs.
-        */
-       if (is_selinux_enabled() && !(zfsflags & ZS_NOCONTEXT)) {
-               (void) strlcat(mntopts, ",context=\"system_u:"
-                   "object_r:file_t:s0\"", sizeof (mntopts));
-               (void) strlcat(mtabopt, ",context=\"system_u:"
-                   "object_r:file_t:s0\"", sizeof (mtabopt));
-       }
-#endif /* HAVE_LIBSELINUX */
-
-
        if (verbose)
                (void) fprintf(stdout, gettext("mount.zfs:\n"
                    "  dataset:    \"%s\"\n  mountpoint: \"%s\"\n"
@@ -480,12 +484,36 @@ main(int argc, char **argv)
                return (MOUNT_USAGE);
        }
 
+       /*
+        * Checks to see if the ZFS_PROP_SELINUX_CONTEXT exists
+        * if it does, create a tmp variable in case it's needed
+        * checks to see if the selinux context is set to the default
+        * if it is, allow the setting of the other context properties
+        * this is needed because the 'context' property overrides others
+        * if it is not the default, set the 'context' property
+        */
+       if (zfs_prop_get(zhp, ZFS_PROP_SELINUX_CONTEXT, prop, sizeof (prop),
+           NULL, NULL, 0, B_FALSE) == 0) {
+               if (strcmp(prop, "none") == 0) {
+                       zfs_selinux_setcontext(zhp, ZFS_PROP_SELINUX_FSCONTEXT,
+                           MNTOPT_FSCONTEXT, mntopts, mtabopt);
+                       zfs_selinux_setcontext(zhp, ZFS_PROP_SELINUX_DEFCONTEXT,
+                           MNTOPT_DEFCONTEXT, mntopts, mtabopt);
+                       zfs_selinux_setcontext(zhp,
+                           ZFS_PROP_SELINUX_ROOTCONTEXT, MNTOPT_ROOTCONTEXT,
+                           mntopts, mtabopt);
+               } else {
+                       __zfs_selinux_setcontext(MNTOPT_CONTEXT,
+                           prop, mntopts, mtabopt);
+               }
+       }
+
        /* treat all snapshots as legacy mount points */
        if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT)
-               (void) strlcpy(legacy, ZFS_MOUNTPOINT_LEGACY, ZFS_MAXPROPLEN);
+               (void) strlcpy(prop, ZFS_MOUNTPOINT_LEGACY, ZFS_MAXPROPLEN);
        else
-               (void) zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, legacy,
-                   sizeof (legacy), NULL, NULL, 0, B_FALSE);
+               (void) zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, prop,
+                   sizeof (prop), NULL, NULL, 0, B_FALSE);
 
        zfs_close(zhp);
        libzfs_fini(g_zfs);
@@ -501,7 +529,7 @@ main(int argc, char **argv)
         * using zfs as your root file system both rc.sysinit/umountroot and
         * systemd depend on 'mount -o remount <mountpoint>' to work.
         */
-       if (zfsutil && (strcmp(legacy, ZFS_MOUNTPOINT_LEGACY) == 0)) {
+       if (zfsutil && (strcmp(prop, ZFS_MOUNTPOINT_LEGACY) == 0)) {
                (void) fprintf(stderr, gettext(
                    "filesystem '%s' cannot be mounted using 'zfs mount'.\n"
                    "Use 'zfs set mountpoint=%s' or 'mount -t zfs %s %s'.\n"
@@ -511,7 +539,7 @@ main(int argc, char **argv)
        }
 
        if (!zfsutil && !(remount || fake) &&
-           strcmp(legacy, ZFS_MOUNTPOINT_LEGACY)) {
+           strcmp(prop, ZFS_MOUNTPOINT_LEGACY)) {
                (void) fprintf(stderr, gettext(
                    "filesystem '%s' cannot be mounted using 'mount'.\n"
                    "Use 'zfs set mountpoint=%s' or 'zfs mount %s'.\n"
diff --git a/config/user-selinux.m4 b/config/user-selinux.m4
deleted file mode 100644 (file)
index 84df6ce..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-dnl #
-dnl # Check to see if the selinux libraries are available.  If they
-dnl # are then they will be consulted during mount to determine if
-dnl # selinux is enabled or disabled.
-dnl #
-AC_DEFUN([ZFS_AC_CONFIG_USER_LIBSELINUX], [
-       AC_ARG_WITH([selinux],
-               [AS_HELP_STRING([--with-selinux],
-               [support selinux @<:@default=check@:>@])],
-               [],
-               [with_selinux=check])
-
-       LIBSELINUX=
-       AS_IF([test "x$with_selinux" != xno], [
-               AC_CHECK_HEADER([selinux/selinux.h], [
-                       AC_CHECK_LIB([selinux], [is_selinux_enabled], [
-                               AC_SUBST([LIBSELINUX], ["-lselinux"])
-                               AC_DEFINE([HAVE_LIBSELINUX], 1,
-                                       [Define if you have selinux])
-                       ], [
-                               AS_IF([test "x$with_selinux" != xcheck],
-                                       [AC_MSG_FAILURE(
-                                       [--with-selinux given but unavailable])
-                               ])
-                       ])
-               ], [
-                       AS_IF([test "x$with_selinux" != xcheck],
-                               [AC_MSG_FAILURE(
-                               [--with-selinux given but unavailable])
-                       ])
-               ])
-       ], [
-               AC_MSG_CHECKING([for selinux support])
-               AC_MSG_RESULT([no])
-       ])
-])
index 6925e56f4b1a856babe658a32a766af9a439db88..4f9963787d580bed62bd62ebb8ff0ce5c5702b53 100644 (file)
@@ -9,6 +9,5 @@ AC_DEFUN([ZFS_AC_CONFIG_USER], [
        ZFS_AC_CONFIG_USER_ZLIB
        ZFS_AC_CONFIG_USER_LIBUUID
        ZFS_AC_CONFIG_USER_LIBBLKID
-       ZFS_AC_CONFIG_USER_LIBSELINUX
        ZFS_AC_CONFIG_USER_FRAME_LARGER_THAN
 ])
index cfcc78b80e98c321fdb5f444bca3f211ee69e0a6..23303d7414d605417241abe09b2d925cec012071 100644 (file)
@@ -143,6 +143,10 @@ typedef enum {
        ZFS_PROP_INCONSISTENT,          /* not exposed to the user */
        ZFS_PROP_SNAPDEV,
        ZFS_PROP_ACLTYPE,
+       ZFS_PROP_SELINUX_CONTEXT,
+       ZFS_PROP_SELINUX_FSCONTEXT,
+       ZFS_PROP_SELINUX_DEFCONTEXT,
+       ZFS_PROP_SELINUX_ROOTCONTEXT,
        ZFS_NUM_PROPS
 } zfs_prop_t;
 
index a4be01d7545934d200505ac29c325b1050762aa1..b57ffee83d4f2ca2596320ee0bf4a0ca8a8c058b 100644 (file)
@@ -47,7 +47,6 @@
 #define        MNTOPT_AUTO     "auto"          /* automount */
 #define        MNTOPT_NOAUTO   "noauto"        /* do not automount */
 #define        MNTOPT_CONTEXT  "context"       /* selinux context */
-#define        MNTOPT_NOCONTEXT "nocontext"    /* No selinux context (zfs-only) */
 #define        MNTOPT_FSCONTEXT "fscontext"    /* selinux fscontext */
 #define        MNTOPT_DEFCONTEXT "defcontext"  /* selinux defcontext */
 #define        MNTOPT_ROOTCONTEXT "rootcontext" /* selinux rootcontext */
@@ -99,6 +98,5 @@
 
 #define        ZS_COMMENT      0x00000000      /* comment */
 #define        ZS_ZFSUTIL      0x00000001      /* caller is zfs(8) */
-#define        ZS_NOCONTEXT    0x00000002      /* do not add selinux context */
 
 #endif /* _SYS_MNTENT_H */
index 60c36fe4e39c09d5e0e3ae2409a66acb878c48fd..b4e2406a22e7a099e19bb01702ddcb287f4f079d 100644 (file)
@@ -75,6 +75,19 @@ Increase verbosity.
 .BI "\-h"
 Print the usage message.
 .TP
+.BI "\-o context"
+This flag sets the SELinux context for all files in the filesytem
+under that mountpoint.
+.TP
+.BI "\-o fscontext"
+This flag sets the SELinux context for the filesytem being mounted.
+.TP
+.BI "\-o defcontext"
+This flag sets the SELinux context for unlabled files.
+.TP
+.BI "\-o rootcontext"
+This flag sets the SELinux context for the root inode of the filesystem.
+.TP
 .BI "\-o legacy"
 This private flag indicates that the
 .I dataset
index 321a297f270a992aa4bb23beefd14bec8f12fc5f..2c540f0597a97057e143e7bfeca610e2a65e722c 100644 (file)
@@ -1298,6 +1298,52 @@ Indicates whether the file system should reject file names that include characte
 .sp
 .LP
 The \fBcasesensitivity\fR, \fBnormalization\fR, and \fButf8only\fR properties are also new permissions that can be assigned to non-privileged users by using the \fBZFS\fR delegated administration feature.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fBcontext\fR=\fBSELinux_User:SElinux_Role:Selinux_Type:Sensitivity_Level\fR\fR
+.ad
+.sp .6
+.RS 4n
+This flag sets the SELinux context for all files in the filesytem under the mountpoint for that filesystem.  See \fBselinux\fR(8) for more information.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fBfscontext\fR=\fBSELinux_User:SElinux_Role:Selinux_Type:Sensitivity_Level\fR\fR
+.ad
+.sp .6
+.RS 4n
+This flag sets the SELinux context for the filesytem being mounted.  See \fBselinux\fR(8) for more information.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fBdefntext\fR=\fBSELinux_User:SElinux_Role:Selinux_Type:Sensitivity_Level\fR\fR
+.ad
+.sp .6
+.RS 4n
+This flag sets the SELinux context for unlabeled files.  See \fBselinux\fR(8) for more information.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+\fB\fBrootcontext\fR=\fBSELinux_User:SElinux_Role:Selinux_Type:Sensitivity_Level\fR\fR
+.ad
+.sp .6
+.RS 4n
+This flag sets the SELinux context for the root inode of the filesystem.  See \fBselinux\fR(8) for more information.
+.RE
+
 .SS "Temporary Mount Point Properties"
 .LP
 When a file system is mounted, either through \fBmount\fR(8) for legacy mounts or the \fBzfs mount\fR command for normal file systems, its mount options are set according to its properties. The correlation between properties and mount options is as follows:
index 98d5bea96cd149e2ca2691f4cd68edf83c3a1546..121b1eb57d220e0d511c43feb5c7da815099273b 100644 (file)
@@ -332,6 +332,18 @@ zfs_prop_init(void)
        zprop_register_string(ZFS_PROP_MLSLABEL, "mlslabel",
            ZFS_MLSLABEL_DEFAULT, PROP_INHERIT, ZFS_TYPE_DATASET,
            "<sensitivity label>", "MLSLABEL");
+       zprop_register_string(ZFS_PROP_SELINUX_CONTEXT, "context",
+           "none", PROP_DEFAULT, ZFS_TYPE_DATASET, "<selinux context>",
+           "CONTEXT");
+       zprop_register_string(ZFS_PROP_SELINUX_FSCONTEXT, "fscontext",
+           "none", PROP_DEFAULT, ZFS_TYPE_DATASET, "<selinux fscontext>",
+           "FSCONTEXT");
+       zprop_register_string(ZFS_PROP_SELINUX_DEFCONTEXT, "defcontext",
+           "none", PROP_DEFAULT, ZFS_TYPE_DATASET, "<selinux defcontext>",
+           "DEFCONTEXT");
+       zprop_register_string(ZFS_PROP_SELINUX_ROOTCONTEXT, "rootcontext",
+           "none", PROP_DEFAULT, ZFS_TYPE_DATASET, "<selinux rootcontext>",
+           "ROOTCONTEXT");
 
        /* readonly number properties */
        zprop_register_number(ZFS_PROP_USED, "used", 0, PROP_READONLY,
index 6425d1e011142b96561b3382cfa8e6700d4f2fab..1e64ac18ea26a51161d4770c38019ac18b51b0a3 100644 (file)
@@ -10,7 +10,6 @@
 
 %bcond_with    debug
 %bcond_with    blkid
-%bcond_with    selinux
 
 
 Name:           @PACKAGE@
@@ -38,9 +37,6 @@ BuildRequires:  libuuid-devel
 %if %{with blkid}
 BuildRequires:  libblkid-devel
 %endif
-%if %{with selinux}
-BuildRequires:  libselinux-devel
-%endif
 %endif
 
 %description
@@ -89,11 +85,6 @@ image which is ZFS aware.
 %else
     %define blkid --without-blkid
 %endif
-%if %{with selinux}
-    %define selinux --with-selinux
-%else
-    %define selinux --without-selinux
-%endif
 
 %setup -q
 
@@ -104,8 +95,7 @@ image which is ZFS aware.
     --with-dracutdir=%{_dracutdir} \
     --disable-static \
     %{debug} \
-    %{blkid} \
-    %{selinux}
+    %{blkid}
 make %{?_smp_mflags}
 
 %install