kern/150206: nmount(2): can't switch root partition to rw using mount flags

Aurelien Jarno aurelien at aurel32.net
Wed Sep 1 22:50:02 UTC 2010


>Number:         150206
>Category:       kern
>Synopsis:       nmount(2): can't switch root partition to rw using mount flags
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Sep 01 22:50:01 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     Aurelien Jarno
>Release:        8.1
>Organization:
>Environment:
FreeBSD freebsd.aurel32.net 8.1-RELEASE FreeBSD 8.1-RELEASE #0: Mon Jul 19 02:55:53 UTC 2010     root at almeida.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  i386
>Description:
The nmount(2) syscall can take filesystem options in two different ways: either via the mount flags or via iovec.

When trying to switch a root partition from ro to rw using mount flags only (this is done for example by busybox to avoid diverging to much from the Linux code), that is using MNT_UPDATE but not MNT_RDONLY, this operation is ignored. This work correctly on a non-root filesystem though.
>How-To-Repeat:

>Fix:
Patch is attached.

Patch attached with submission follows:

--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -559,10 +559,10 @@
 	struct vfsopt *opt, *noro_opt, *tmp_opt;
 	char *fstype, *fspath, *errmsg;
 	int error, fstypelen, fspathlen, errmsg_len, errmsg_pos;
-	int has_rw, has_noro;
+	int has_noro;
 
 	errmsg = fspath = NULL;
-	errmsg_len = has_noro = has_rw = fspathlen = 0;
+	errmsg_len = has_noro = fspathlen = 0;
 	errmsg_pos = -1;
 
 	error = vfs_buildopts(fsoptions, &optlist);
@@ -659,10 +659,8 @@
 			fsflags &= ~MNT_RDONLY;
 			has_noro = 1;
 		}
-		else if (strcmp(opt->name, "rw") == 0) {
+		else if (strcmp(opt->name, "rw") == 0)
 			fsflags &= ~MNT_RDONLY;
-			has_rw = 1;
-		}
 		else if (strcmp(opt->name, "ro") == 0)
 			fsflags |= MNT_RDONLY;
 		else if (strcmp(opt->name, "rdonly") == 0) {
@@ -684,7 +682,7 @@
 	 * we need a mount option "noro", since in vfs_mergeopts(),
 	 * "noro" will cancel "ro", but "rw" will not do anything.
 	 */
-	if (has_rw && !has_noro) {
+	if (!(fsflags & MNT_RDONLY) && !has_noro) {
 		noro_opt = malloc(sizeof(struct vfsopt), M_MOUNT, M_WAITOK);
 		noro_opt->name = strdup("noro", M_MOUNT);
 		noro_opt->value = NULL;


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list