>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     r...@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:
_______________________________________________
freebsd-bugs@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"

Reply via email to