Skip to content

Commit

Permalink
Adds full selinux support
Browse files Browse the repository at this point in the history
You can now set [root,dev,fs,]context attributes

Signed-off-by: Matthew Thode <prometheanfire@gentoo.org>
  • Loading branch information
prometheanfire committed Dec 14, 2013
1 parent dda12da commit 1818ddf
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 22 deletions.
80 changes: 58 additions & 22 deletions cmd/mount_zfs/mount_zfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -334,11 +334,38 @@ mtab_update(char *dataset, char *mntpoint, char *type, char *mntopts)
return (MOUNT_SUCCESS);
}

#ifdef HAVE_LIBSELINUX

This comment has been minimized.

Copy link
@behlendorf

behlendorf Dec 16, 2013

I believe we can safely drop the HAVE_LIBSELINUX wrapper and autoconf checks. They were only strictly needed because is_selinux_enabled() was a library function which we needed to ensure was available. Since you've removed that call we can drop all of that infrastructure including linking against $(LIBSELINUX) in cmd/mount_zfs/Makefile.am.

static void
__zfs_selinux_setcontext(const char *name, const char *context, char *mntopts,
char *mtabopt)

This comment has been minimized.

Copy link
@behlendorf

behlendorf Dec 16, 2013

[style] Just 4 spaces, no tab. See parse_option() above as an example. I'm a little surprised cstyle.pl didn't flag this, but I guess it is just a script.

{
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);

This comment has been minimized.

Copy link
@behlendorf

behlendorf Dec 16, 2013

[style] Remove the tailing whitespace before the }. I do like these helper functions they make it nice and readable.

}

static void
zfs_selinux_setcontext(zfs_handle_t *zhp, zfs_prop_t zpt, const char *name,
char *mntopts, char *mtabopt)

This comment has been minimized.

Copy link
@behlendorf

behlendorf Dec 16, 2013

[style] Just 4 spaces, no tab. See parse_option() above as an example.

{
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);

This comment has been minimized.

Copy link
@behlendorf

behlendorf Dec 16, 2013

[style] Each level should be indented with a tab, no spaces. 4 spaces are only used when a line needs to be wrapped at 80 characters.

};

This comment has been minimized.

Copy link
@behlendorf

behlendorf Dec 16, 2013

No ; after the }.

}
#endif

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' };
Expand Down Expand Up @@ -433,21 +460,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)) {

This comment has been minimized.

Copy link
@behlendorf

behlendorf Dec 16, 2013

ZS_NOCONTEXT is now no longer used. We should remove it from lib/libspl/include/sys/mntent.h and replace it with ZS_COMMENT in the option_map[].

(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"
Expand Down Expand Up @@ -476,12 +488,36 @@ main(int argc, char **argv)
return (MOUNT_USAGE);
}

#ifdef HAVE_LIBSELINUX
/*
* 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,
"fscontext", mntopts, mtabopt);
zfs_selinux_setcontext(zhp, ZFS_PROP_SELINUX_DEFCONTEXT,
"defcontext", mntopts, mtabopt);
zfs_selinux_setcontext(zhp, ZFS_PROP_SELINUX_ROOTCONTEXT,
"rootcontext", mntopts, mtabopt);
} else {
__zfs_selinux_setcontext("context", prop, mntopts, mtabopt);
};
}

This comment has been minimized.

Copy link
@behlendorf

behlendorf Dec 16, 2013

Much better. As mentioned above we should be able to drop the HAVE_LIBSELINUX wrapper. Also, it might be cleaner to use the MNTOPT_CONTEXT, MNTOPT_FSCONTEXT, MNTOPT_DEFCONTEXT, MNTOPT_ROOTCONTEXT macros in zfs_selinux_setcontext().

[style] Same tab indent rules as mentioned above.
[style] No ; after the }.

This comment has been minimized.

Copy link
@prometheanfire

prometheanfire Dec 18, 2013

Author Owner

I'm not sure what you mean by using those MNTOPTs, do you mean to replace ZFS_PROP_SELINUX_FSCONTEXT with MNTOPT_FSCONTEXT for instance?

This comment has been minimized.

Copy link
@behlendorf

behlendorf Dec 18, 2013

No, I was thinking that replacing the "fscontext" string with MNTOPT_FSCONTEXT would be cleaner. But I could go either way on this if you feel strongly about it. For example.

-        zfs_selinux_setcontext(zhp, ZFS_PROP_SELINUX_FSCONTEXT,
-          "fscontext", mntopts, mtabopt);
+        zfs_selinux_setcontext(zhp, ZFS_PROP_SELINUX_FSCONTEXT,
+          MNTOPT_FSCONTEXT, mntopts, mtabopt);
#endif /* HAVE_LIBSELINUX */

/* 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);
Expand All @@ -497,17 +533,17 @@ 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)) {
if (zfsutil && !strcmp(prop, ZFS_MOUNTPOINT_LEGACY)) {
(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"
"See zfs(8) for more information.\n"),
dataset, mntpoint, dataset, mntpoint);
dataset, mntpoint, dataset, mntpoint);
return (MOUNT_USAGE);
}

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"
Expand Down
4 changes: 4 additions & 0 deletions include/sys/fs/zfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
13 changes: 13 additions & 0 deletions man/man8/mount.zfs.8
Original file line number Diff line number Diff line change
Expand Up @@ -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

This comment has been minimized.

Copy link
@behlendorf

behlendorf Dec 16, 2013

Basic documentation must also be added to the Native Properties section of the zfs(8) man page. At a minimum the new properties need to be added to the list of support properties. They shouldn't briefly describe the expected syntax, what they do, and refer the user to mount(8) for a fuller description.

.BI "\-o legacy"
This private flag indicates that the
.I dataset
Expand Down
12 changes: 12 additions & 0 deletions module/zcommon/zfs_prop.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

1 comment on commit 1818ddf

@behlendorf
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@prometheanfire On the whole this looks really good, just a little more cleanup and we should be there!

Please sign in to comment.