Strip 'zfsutil,remount' from /etc/mtab

When updating /etc/mtab we should be careful and strip certain
options.  In particular, we need to strip 'zfsutil' because if
we don't the mount utility will helpfull provide it to the
mount helper when we issue mount(8) again.  This subverts the
check that the caller is zfs(8) and not mount(8).
This commit is contained in:
Brian Behlendorf 2011-03-15 11:17:33 -07:00
parent 093aa69286
commit 3aff775555

View File

@ -72,13 +72,11 @@ static const option_map_t option_map[] = {
#ifdef MS_STRICTATIME
{ MNTOPT_DFRATIME, MS_STRICTATIME, ZS_COMMENT },
#endif
#ifdef HAVE_SELINUX
{ 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 },
#endif
#ifdef MS_I_VERSION
{ MNTOPT_IVERSION, MS_I_VERSION, ZS_COMMENT },
#endif
@ -158,10 +156,10 @@ out:
* otherwise they are considered fatal are copied in to badopt.
*/
static int
parse_options(char *mntopts, unsigned long *mntflags,
unsigned long *zfsflags, int sloppy, char *badopt)
parse_options(char *mntopts, unsigned long *mntflags, unsigned long *zfsflags,
int sloppy, char *badopt, char *mtabopt)
{
int error = 0, quote = 0, flag = 0;
int error = 0, quote = 0, flag = 0, count = 0;
char *ptr, *opt, *opts;
opts = strdup(mntopts);
@ -197,6 +195,16 @@ parse_options(char *mntopts, unsigned long *mntflags,
if (error) {
strcpy(badopt, opt);
goto out;
}
if (!(*mntflags & MS_REMOUNT) &&
!(*zfsflags & ZS_ZFSUTIL)) {
if (count > 0)
strlcat(mtabopt, ",", MNT_LINE_MAX);
strlcat(mtabopt, opt, MNT_LINE_MAX);
count++;
}
opt = NULL;
@ -297,6 +305,7 @@ main(int argc, char **argv)
char legacy[ZFS_MAXPROPLEN];
char mntopts[MNT_LINE_MAX] = { '\0' };
char badopt[MNT_LINE_MAX] = { '\0' };
char mtabopt[MNT_LINE_MAX] = { '\0' };
char *dataset, *mntpoint;
unsigned long mntflags = 0, zfsflags = 0, remount_ro = 0;
int sloppy = 0, fake = 0, verbose = 0, nomtab = 0, zfsutil = 0;
@ -356,24 +365,25 @@ main(int argc, char **argv)
mntpoint = argv[1];
/* validate mount options and set mntflags */
error = parse_options(mntopts, &mntflags, &zfsflags, sloppy, badopt);
error = parse_options(mntopts, &mntflags, &zfsflags, sloppy,
badopt, mtabopt);
if (error) {
switch (error) {
case ENOMEM:
(void) fprintf(stderr, gettext("filesystem '%s' "
"cannot be mounted due to a memory allocation "
"failure\n"), dataset);
"failure.\n"), dataset);
return (MOUNT_SYSERR);
case EINVAL:
case ENOENT:
(void) fprintf(stderr, gettext("filesystem '%s' "
"cannot be mounted of due to the invalid option "
"'%s'\n"), dataset, badopt);
"cannot be mounted of due invalid option "
"'%s'.\n"), dataset, badopt);
(void) fprintf(stderr, gettext("Use the '-s' option "
"to ignore the bad mount option.\n"));
return (MOUNT_USAGE);
default:
(void) fprintf(stderr, gettext("filesystem '%s' "
"cannot be mounted due to internal error %d\n"),
"cannot be mounted due to internal error %d.\n"),
dataset, error);
return (MOUNT_SOFTWARE);
}
@ -386,9 +396,12 @@ main(int argc, char **argv)
* 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))
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 */
@ -396,8 +409,8 @@ main(int argc, char **argv)
(void) fprintf(stdout, gettext("mount.zfs:\n"
" dataset: \"%s\"\n mountpoint: \"%s\"\n"
" mountflags: 0x%lx\n zfsflags: 0x%lx\n"
" mountopts: \"%s\"\n\n"),
dataset, mntpoint, mntflags, zfsflags, mntopts);
" mountopts: \"%s\"\n mtabopts: \"%s\"\n"),
dataset, mntpoint, mntflags, zfsflags, mntopts, mtabopt);
if (mntflags & MS_REMOUNT)
nomtab = 1;
@ -472,7 +485,7 @@ main(int argc, char **argv)
}
if (!nomtab && mtab_is_writeable()) {
error = mtab_update(dataset, mntpoint, MNTTYPE_ZFS, mntopts);
error = mtab_update(dataset, mntpoint, MNTTYPE_ZFS, mtabopt);
if (error)
return (error);
}