Bug 116980 - [msdosfs] [patch] mount_msdosfs(8) resets some flags for 'update' mount
Summary: [msdosfs] [patch] mount_msdosfs(8) resets some flags for 'update' mount
Status: Open
Alias: None
Product: Base System
Classification: Unclassified
Component: bin (show other bugs)
Version: 6.2-STABLE
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-bugs mailing list
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-10-06 20:30 UTC by Eugene Grosbein
Modified: 2018-01-03 05:16 UTC (History)
0 users

See Also:


Attachments
file.diff (2.31 KB, patch)
2007-10-06 20:30 UTC, Eugene Grosbein
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Eugene Grosbein 2007-10-06 20:30:00 UTC
	"mount -t msdosfs -u -o rw" resets uid, gid, mask and dirmask
	to defauls but should keep current values.

Fix: mount_msdosfs(8) should not set defaults for update.
How-To-Repeat: 
	1. Create FS with a file:

# dd if=/dev/zero bs=1k count=1440 of=image
# mdconfig -a -t vnode -f image
# newfs_msdos -f 1440 /dev/md0
# mount_msdosfs /dev/md0 /mnt/tmp
# touch /mnt/tmp/file
# umount /mnt/tmp

	2. Mount it with convenient flags, so directories are searchable
	and files are not executable, and read-only:

# mount_msdosfs -o ro -M 755 -m 644 /dev/md0 /mnt/tmp

	Make sure it works, file is not executable:

# ls -l /mnt/tmp
total 0
-rw-r--r--  1 root  wheel  0 Oct  7 03:05 file

	Now remount it read-write and see that mask has been reset:

# mount -u -o rw /mnt/tmp
# ls -l /mnt/tmp
total 0
-rwxr-xr-x  1 root  wheel  0 Oct  7 03:05 file
Comment 1 EugeneGrosbein 2007-10-14 15:48:55 UTC
Hi!

Same patch, suitable for 7.0-PRERELEASE:

--- sbin/mount_msdosfs/mount_msdosfs.c.orig	2007-01-29 08:49:08.000000000 +0700
+++ sbin/mount_msdosfs/mount_msdosfs.c	2007-10-14 18:37:08.000000000 +0800
@@ -69,7 +69,7 @@
 	struct iovec *iov = NULL;
 	int iovlen = 0;
 	struct stat sb;
-	int c, mntflags, set_gid, set_uid, set_mask, set_dirmask;
+	int c, mntflags, set_gid, set_uid, set_mask, set_dirmask, update = 0;
 	char *dev, *dir, mntpath[MAXPATHLEN], *csp;
 	char fstype[] = "msdosfs";
 	char errmsg[255] = {0};
@@ -134,6 +134,7 @@
 				*p = '\0';
 				val = p + 1;
 			}
+			update = update || !strcmp(optarg, "update");
 			build_iovec(&iov, &iovlen, optarg, val, (size_t)-1);
 			}
 			break;
@@ -166,13 +167,15 @@
 	if (optind + 2 != argc)
 		usage();
 
-	if (set_mask && !set_dirmask) {
-		dirmask = mask;
-		set_dirmask = 1;
-	}
-	else if (set_dirmask && !set_mask) {
-		mask = dirmask;
-		set_mask = 1;
+	if (!update) {
+		if (set_mask && !set_dirmask) {
+			dirmask = mask;
+			set_dirmask = 1;
+		}
+		else if (set_dirmask && !set_mask) {
+			mask = dirmask;
+			set_mask = 1;
+		}
 	}
 
 	dev = argv[optind];
@@ -196,27 +199,37 @@
 	(void)checkpath(dir, mntpath);
 	(void)rmslashes(dev, dev);
 
-	if (!set_gid || !set_uid || !set_mask) {
+ 	if (!update && (!set_gid || !set_uid || !set_mask)) {
 		if (stat(mntpath, &sb) == -1)
 			err(EX_OSERR, "stat %s", mntpath);
-
-		if (!set_uid)
+ 		if (!set_uid) {
 			uid = sb.st_uid;
-		if (!set_gid)
+ 			set_uid = 1;
+ 		}
+ 		if (!set_gid) {
 			gid = sb.st_gid;
-		if (!set_mask)
+ 			set_gid = 1;
+ 		}
+ 		if (!set_mask) {
 			mask = dirmask =
 				sb.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
+ 			set_mask = set_dirmask = 1;
+ 		}
 	}
 
 	build_iovec(&iov, &iovlen, "fstype", fstype, (size_t)-1);
 	build_iovec(&iov, &iovlen, "fspath", mntpath, (size_t)-1);
 	build_iovec(&iov, &iovlen, "from", dev, (size_t)-1);
 	build_iovec(&iov, &iovlen, "errmsg", errmsg, sizeof(errmsg));
-	build_iovec_argf(&iov, &iovlen, "uid", "%d", uid);
-	build_iovec_argf(&iov, &iovlen, "gid", "%u", gid);
-	build_iovec_argf(&iov, &iovlen, "mask", "%u", mask);
-	build_iovec_argf(&iov, &iovlen, "dirmask", "%u", dirmask);
+
+ 	if (set_uid)
+ 		build_iovec_argf(&iov, &iovlen, "uid", "%d", uid);
+ 	if (set_gid)
+ 		build_iovec_argf(&iov, &iovlen, "gid", "%u", gid);
+ 	if (set_mask)
+ 		build_iovec_argf(&iov, &iovlen, "mask", "%u", mask);
+ 	if (set_dirmask)
+ 		build_iovec_argf(&iov, &iovlen, "dirmask", "%u", dirmask);
 
 	if (nmount(iov, iovlen, mntflags) < 0)
 		err(1, "%s: %s", dev, errmsg);
Comment 2 Bruce Evans freebsd_committer 2007-10-15 06:37:43 UTC
On Sun, 14 Oct 2007 EugeneGrosbein@grosbein.pp.ru wrote:

> Subject: Re: bin/116980: [patch] [msdosfs] mount_msdosfs(8) resets some flags for 'update' mount

> Same patch, suitable for 7.0-PRERELEASE:

You should be using -ocurrent.  Without -ocurrent, all flags not
explicily mentioned in the options list are supposed to be reset.
However, -ocurrent has apparently never actually worked except for
generic flags, since the generic level of mount(1) cannot determine
the current settings of non-generic flags itself and has no way to
pass the -current option to the fs-specific mount utilities.  This
also breaks the display of the current settings when no mount point
is specified.

This problem affects all file systems, and its fix shouldn't involve
changing the semantics of mount without -ocurrent, so it cannot be
fixed as in the submitted patch.

> --- sbin/mount_msdosfs/mount_msdosfs.c.orig	2007-01-29 08:49:08.000000000 +0700
> +++ sbin/mount_msdosfs/mount_msdosfs.c	2007-10-14 18:37:08.000000000 +0800
> @@ -69,7 +69,7 @@
>  	struct iovec *iov = NULL;
>  	int iovlen = 0;
>  	struct stat sb;
> -	int c, mntflags, set_gid, set_uid, set_mask, set_dirmask;
> +	int c, mntflags, set_gid, set_uid, set_mask, set_dirmask, update = 0;
>  	char *dev, *dir, mntpath[MAXPATHLEN], *csp;
>  	char fstype[] = "msdosfs";
>  	char errmsg[255] = {0};

Style bug: initialization in declaration.  Some nearby lines have the same
style bug, but style bugs on the changed line were limited to disorder.

> @@ -134,6 +134,7 @@
>  				*p = '\0';
>  				val = p + 1;
>  			}
> +			update = update || !strcmp(optarg, "update");
>  			build_iovec(&iov, &iovlen, optarg, val, (size_t)-1);
>  			}
>  			break;

This and the following changes might be correct with a test of "current"
instead of "update".

Style bug: boolean comparison of non-boolean `strcmp()'.  This style bug is
missing for all other instances of strcmp() in this file.

The (old) logic for resetting to defaults also has problems.  Defaults
for uids, gids and masks are taken from the current values for the mount
point.  However, previous overrides of the defaults affect the current
value, so it is difficult to determine the values to reset to.  This
causes strange behaviour like the following:

 	# mount_msdosfs /dev/foo /foo
 	# # mode is now 555 for /foo and for regular files under /foo, say
 	# mount -u -o -M755,-m644 /foo  # set nicer masks
 	# mount -u /foo  # try to reset
 	# # mode is now 755 for /foo and for regular files under /foo
 	# # The -M setting is apparently preserved, but that is an illusion --
 	# # the setting is the default and the default is wrong (it is
 	# # taken from the current value for the mount point but should be
 	# # taken from the current value for the mounted-on point.
 	# # The -m setting is neither reset nor apparently-preserved --
 	# # again, it is the default and the default is wrong (same as for
 	# # -M since the directory perms are used for regular files unless
 	# # -m is specified.

I think I saw problems caused by this for nfs yesterday.  I was toggling
-T and async, and thought that mount -u doesn't support toggling -T,
so I was remounting to toggle -T.  Then toggling async using mount -u
caused mysterious hangs if I forgot to match the current setting of
-T in the option list for -u.  I think the hangs are new -- apparently,
toggling -T used to work but now causes hangs.

Bruce
Comment 3 Mark Linimon freebsd_committer freebsd_triage 2009-05-18 05:28:52 UTC
Responsible Changed
From-To: freebsd-bugs->freebsd-fs

Over to maintainer(s).
Comment 4 Eitan Adler freebsd_committer freebsd_triage 2017-12-31 08:00:44 UTC
For bugs matching the following criteria:

Status: In Progress Changed: (is less than) 2014-06-01

Reset to default assignee and clear in-progress tags.

Mail being skipped