Skip to content

Commit 11b9ec2

Browse files
prometheanfirebehlendorf
authored andcommitted
Add full SELinux support
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 <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Signed-off-by: Richard Yao <[email protected]> Closes #1504
1 parent d1d7e26 commit 11b9ec2

File tree

10 files changed

+134
-82
lines changed

10 files changed

+134
-82
lines changed

cmd/mount_zfs/Makefile.am

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,3 @@ mount_zfs_LDADD = \
2020
$(top_builddir)/lib/libzpool/libzpool.la \
2121
$(top_builddir)/lib/libzfs/libzfs.la \
2222
$(top_builddir)/lib/libzfs_core/libzfs_core.la
23-
24-
mount_zfs_LDADD += $(LIBSELINUX)

cmd/mount_zfs/mount_zfs.c

Lines changed: 58 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,6 @@
3131
#include <sys/stat.h>
3232
#include <libzfs.h>
3333
#include <locale.h>
34-
#ifdef HAVE_LIBSELINUX
35-
#include <selinux/selinux.h>
36-
#endif /* HAVE_LIBSELINUX */
3734

3835
libzfs_handle_t *g_zfs;
3936

@@ -77,11 +74,10 @@ static const option_map_t option_map[] = {
7774
#ifdef MS_STRICTATIME
7875
{ MNTOPT_DFRATIME, MS_STRICTATIME, ZS_COMMENT },
7976
#endif
80-
{ MNTOPT_CONTEXT, MS_COMMENT, ZS_NOCONTEXT },
81-
{ MNTOPT_NOCONTEXT, MS_COMMENT, ZS_NOCONTEXT },
82-
{ MNTOPT_FSCONTEXT, MS_COMMENT, ZS_NOCONTEXT },
83-
{ MNTOPT_DEFCONTEXT, MS_COMMENT, ZS_NOCONTEXT },
84-
{ MNTOPT_ROOTCONTEXT, MS_COMMENT, ZS_NOCONTEXT },
77+
{ MNTOPT_CONTEXT, MS_COMMENT, ZS_COMMENT },
78+
{ MNTOPT_FSCONTEXT, MS_COMMENT, ZS_COMMENT },
79+
{ MNTOPT_DEFCONTEXT, MS_COMMENT, ZS_COMMENT },
80+
{ MNTOPT_ROOTCONTEXT, MS_COMMENT, ZS_COMMENT },
8581
#ifdef MS_I_VERSION
8682
{ MNTOPT_IVERSION, MS_I_VERSION, ZS_COMMENT },
8783
#endif
@@ -338,11 +334,35 @@ mtab_update(char *dataset, char *mntpoint, char *type, char *mntopts)
338334
return (MOUNT_SUCCESS);
339335
}
340336

337+
static void
338+
__zfs_selinux_setcontext(const char *name, const char *context, char *mntopts,
339+
char *mtabopt)
340+
{
341+
char tmp[MNT_LINE_MAX];
342+
343+
snprintf(tmp, MNT_LINE_MAX, ",%s=\"%s\"", name, context);
344+
strlcat(mntopts, tmp, MNT_LINE_MAX);
345+
strlcat(mtabopt, tmp, MNT_LINE_MAX);
346+
}
347+
348+
static void
349+
zfs_selinux_setcontext(zfs_handle_t *zhp, zfs_prop_t zpt, const char *name,
350+
char *mntopts, char *mtabopt)
351+
{
352+
char context[ZFS_MAXPROPLEN];
353+
354+
if (zfs_prop_get(zhp, zpt, context, sizeof (context),
355+
NULL, NULL, 0, B_FALSE) == 0) {
356+
if (strcmp(context, "none") != 0)
357+
__zfs_selinux_setcontext(name, context, mntopts, mtabopt);
358+
}
359+
}
360+
341361
int
342362
main(int argc, char **argv)
343363
{
344364
zfs_handle_t *zhp;
345-
char legacy[ZFS_MAXPROPLEN];
365+
char prop[ZFS_MAXPROPLEN];
346366
char mntopts[MNT_LINE_MAX] = { '\0' };
347367
char badopt[MNT_LINE_MAX] = { '\0' };
348368
char mtabopt[MNT_LINE_MAX] = { '\0' };
@@ -437,22 +457,6 @@ main(int argc, char **argv)
437457
}
438458
}
439459

440-
#ifdef HAVE_LIBSELINUX
441-
/*
442-
* Automatically add the default zfs context when selinux is enabled
443-
* and the caller has not specified their own context. This must be
444-
* done until zfs is added to the default selinux policy configuration
445-
* as a known filesystem type which supports xattrs.
446-
*/
447-
if (is_selinux_enabled() && !(zfsflags & ZS_NOCONTEXT)) {
448-
(void) strlcat(mntopts, ",context=\"system_u:"
449-
"object_r:file_t:s0\"", sizeof (mntopts));
450-
(void) strlcat(mtabopt, ",context=\"system_u:"
451-
"object_r:file_t:s0\"", sizeof (mtabopt));
452-
}
453-
#endif /* HAVE_LIBSELINUX */
454-
455-
456460
if (verbose)
457461
(void) fprintf(stdout, gettext("mount.zfs:\n"
458462
" dataset: \"%s\"\n mountpoint: \"%s\"\n"
@@ -480,12 +484,36 @@ main(int argc, char **argv)
480484
return (MOUNT_USAGE);
481485
}
482486

487+
/*
488+
* Checks to see if the ZFS_PROP_SELINUX_CONTEXT exists
489+
* if it does, create a tmp variable in case it's needed
490+
* checks to see if the selinux context is set to the default
491+
* if it is, allow the setting of the other context properties
492+
* this is needed because the 'context' property overrides others
493+
* if it is not the default, set the 'context' property
494+
*/
495+
if (zfs_prop_get(zhp, ZFS_PROP_SELINUX_CONTEXT, prop, sizeof (prop),
496+
NULL, NULL, 0, B_FALSE) == 0) {
497+
if (strcmp(prop, "none") == 0) {
498+
zfs_selinux_setcontext(zhp, ZFS_PROP_SELINUX_FSCONTEXT,
499+
MNTOPT_FSCONTEXT, mntopts, mtabopt);
500+
zfs_selinux_setcontext(zhp, ZFS_PROP_SELINUX_DEFCONTEXT,
501+
MNTOPT_DEFCONTEXT, mntopts, mtabopt);
502+
zfs_selinux_setcontext(zhp,
503+
ZFS_PROP_SELINUX_ROOTCONTEXT, MNTOPT_ROOTCONTEXT,
504+
mntopts, mtabopt);
505+
} else {
506+
__zfs_selinux_setcontext(MNTOPT_CONTEXT,
507+
prop, mntopts, mtabopt);
508+
}
509+
}
510+
483511
/* treat all snapshots as legacy mount points */
484512
if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT)
485-
(void) strlcpy(legacy, ZFS_MOUNTPOINT_LEGACY, ZFS_MAXPROPLEN);
513+
(void) strlcpy(prop, ZFS_MOUNTPOINT_LEGACY, ZFS_MAXPROPLEN);
486514
else
487-
(void) zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, legacy,
488-
sizeof (legacy), NULL, NULL, 0, B_FALSE);
515+
(void) zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, prop,
516+
sizeof (prop), NULL, NULL, 0, B_FALSE);
489517

490518
zfs_close(zhp);
491519
libzfs_fini(g_zfs);
@@ -501,7 +529,7 @@ main(int argc, char **argv)
501529
* using zfs as your root file system both rc.sysinit/umountroot and
502530
* systemd depend on 'mount -o remount <mountpoint>' to work.
503531
*/
504-
if (zfsutil && (strcmp(legacy, ZFS_MOUNTPOINT_LEGACY) == 0)) {
532+
if (zfsutil && (strcmp(prop, ZFS_MOUNTPOINT_LEGACY) == 0)) {
505533
(void) fprintf(stderr, gettext(
506534
"filesystem '%s' cannot be mounted using 'zfs mount'.\n"
507535
"Use 'zfs set mountpoint=%s' or 'mount -t zfs %s %s'.\n"
@@ -511,7 +539,7 @@ main(int argc, char **argv)
511539
}
512540

513541
if (!zfsutil && !(remount || fake) &&
514-
strcmp(legacy, ZFS_MOUNTPOINT_LEGACY)) {
542+
strcmp(prop, ZFS_MOUNTPOINT_LEGACY)) {
515543
(void) fprintf(stderr, gettext(
516544
"filesystem '%s' cannot be mounted using 'mount'.\n"
517545
"Use 'zfs set mountpoint=%s' or 'zfs mount %s'.\n"

config/user-selinux.m4

Lines changed: 0 additions & 36 deletions
This file was deleted.

config/user.m4

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,5 @@ AC_DEFUN([ZFS_AC_CONFIG_USER], [
99
ZFS_AC_CONFIG_USER_ZLIB
1010
ZFS_AC_CONFIG_USER_LIBUUID
1111
ZFS_AC_CONFIG_USER_LIBBLKID
12-
ZFS_AC_CONFIG_USER_LIBSELINUX
1312
ZFS_AC_CONFIG_USER_FRAME_LARGER_THAN
1413
])

include/sys/fs/zfs.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,10 @@ typedef enum {
143143
ZFS_PROP_INCONSISTENT, /* not exposed to the user */
144144
ZFS_PROP_SNAPDEV,
145145
ZFS_PROP_ACLTYPE,
146+
ZFS_PROP_SELINUX_CONTEXT,
147+
ZFS_PROP_SELINUX_FSCONTEXT,
148+
ZFS_PROP_SELINUX_DEFCONTEXT,
149+
ZFS_PROP_SELINUX_ROOTCONTEXT,
146150
ZFS_NUM_PROPS
147151
} zfs_prop_t;
148152

lib/libspl/include/sys/mntent.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
#define MNTOPT_AUTO "auto" /* automount */
4848
#define MNTOPT_NOAUTO "noauto" /* do not automount */
4949
#define MNTOPT_CONTEXT "context" /* selinux context */
50-
#define MNTOPT_NOCONTEXT "nocontext" /* No selinux context (zfs-only) */
5150
#define MNTOPT_FSCONTEXT "fscontext" /* selinux fscontext */
5251
#define MNTOPT_DEFCONTEXT "defcontext" /* selinux defcontext */
5352
#define MNTOPT_ROOTCONTEXT "rootcontext" /* selinux rootcontext */
@@ -99,6 +98,5 @@
9998

10099
#define ZS_COMMENT 0x00000000 /* comment */
101100
#define ZS_ZFSUTIL 0x00000001 /* caller is zfs(8) */
102-
#define ZS_NOCONTEXT 0x00000002 /* do not add selinux context */
103101

104102
#endif /* _SYS_MNTENT_H */

man/man8/mount.zfs.8

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,19 @@ Increase verbosity.
7575
.BI "\-h"
7676
Print the usage message.
7777
.TP
78+
.BI "\-o context"
79+
This flag sets the SELinux context for all files in the filesytem
80+
under that mountpoint.
81+
.TP
82+
.BI "\-o fscontext"
83+
This flag sets the SELinux context for the filesytem being mounted.
84+
.TP
85+
.BI "\-o defcontext"
86+
This flag sets the SELinux context for unlabled files.
87+
.TP
88+
.BI "\-o rootcontext"
89+
This flag sets the SELinux context for the root inode of the filesystem.
90+
.TP
7891
.BI "\-o legacy"
7992
This private flag indicates that the
8093
.I dataset

man/man8/zfs.8

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,6 +1298,52 @@ Indicates whether the file system should reject file names that include characte
12981298
.sp
12991299
.LP
13001300
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.
1301+
.RE
1302+
1303+
.sp
1304+
.ne 2
1305+
.mk
1306+
.na
1307+
\fB\fBcontext\fR=\fBSELinux_User:SElinux_Role:Selinux_Type:Sensitivity_Level\fR\fR
1308+
.ad
1309+
.sp .6
1310+
.RS 4n
1311+
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.
1312+
.RE
1313+
1314+
.sp
1315+
.ne 2
1316+
.mk
1317+
.na
1318+
\fB\fBfscontext\fR=\fBSELinux_User:SElinux_Role:Selinux_Type:Sensitivity_Level\fR\fR
1319+
.ad
1320+
.sp .6
1321+
.RS 4n
1322+
This flag sets the SELinux context for the filesytem being mounted. See \fBselinux\fR(8) for more information.
1323+
.RE
1324+
1325+
.sp
1326+
.ne 2
1327+
.mk
1328+
.na
1329+
\fB\fBdefntext\fR=\fBSELinux_User:SElinux_Role:Selinux_Type:Sensitivity_Level\fR\fR
1330+
.ad
1331+
.sp .6
1332+
.RS 4n
1333+
This flag sets the SELinux context for unlabeled files. See \fBselinux\fR(8) for more information.
1334+
.RE
1335+
1336+
.sp
1337+
.ne 2
1338+
.mk
1339+
.na
1340+
\fB\fBrootcontext\fR=\fBSELinux_User:SElinux_Role:Selinux_Type:Sensitivity_Level\fR\fR
1341+
.ad
1342+
.sp .6
1343+
.RS 4n
1344+
This flag sets the SELinux context for the root inode of the filesystem. See \fBselinux\fR(8) for more information.
1345+
.RE
1346+
13011347
.SS "Temporary Mount Point Properties"
13021348
.LP
13031349
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:

module/zcommon/zfs_prop.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,18 @@ zfs_prop_init(void)
332332
zprop_register_string(ZFS_PROP_MLSLABEL, "mlslabel",
333333
ZFS_MLSLABEL_DEFAULT, PROP_INHERIT, ZFS_TYPE_DATASET,
334334
"<sensitivity label>", "MLSLABEL");
335+
zprop_register_string(ZFS_PROP_SELINUX_CONTEXT, "context",
336+
"none", PROP_DEFAULT, ZFS_TYPE_DATASET, "<selinux context>",
337+
"CONTEXT");
338+
zprop_register_string(ZFS_PROP_SELINUX_FSCONTEXT, "fscontext",
339+
"none", PROP_DEFAULT, ZFS_TYPE_DATASET, "<selinux fscontext>",
340+
"FSCONTEXT");
341+
zprop_register_string(ZFS_PROP_SELINUX_DEFCONTEXT, "defcontext",
342+
"none", PROP_DEFAULT, ZFS_TYPE_DATASET, "<selinux defcontext>",
343+
"DEFCONTEXT");
344+
zprop_register_string(ZFS_PROP_SELINUX_ROOTCONTEXT, "rootcontext",
345+
"none", PROP_DEFAULT, ZFS_TYPE_DATASET, "<selinux rootcontext>",
346+
"ROOTCONTEXT");
335347

336348
/* readonly number properties */
337349
zprop_register_number(ZFS_PROP_USED, "used", 0, PROP_READONLY,

rpm/generic/zfs.spec.in

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
%bcond_with debug
1212
%bcond_with blkid
13-
%bcond_with selinux
1413

1514

1615
Name: @PACKAGE@
@@ -38,9 +37,6 @@ BuildRequires: libuuid-devel
3837
%if %{with blkid}
3938
BuildRequires: libblkid-devel
4039
%endif
41-
%if %{with selinux}
42-
BuildRequires: libselinux-devel
43-
%endif
4440
%endif
4541

4642
%description
@@ -89,11 +85,6 @@ image which is ZFS aware.
8985
%else
9086
%define blkid --without-blkid
9187
%endif
92-
%if %{with selinux}
93-
%define selinux --with-selinux
94-
%else
95-
%define selinux --without-selinux
96-
%endif
9788

9889
%setup -q
9990

@@ -104,8 +95,7 @@ image which is ZFS aware.
10495
--with-dracutdir=%{_dracutdir} \
10596
--disable-static \
10697
%{debug} \
107-
%{blkid} \
108-
%{selinux}
98+
%{blkid}
10999
make %{?_smp_mflags}
110100

111101
%install

0 commit comments

Comments
 (0)