Author: kib
Date: Wed Jun 10 02:27:00 2015
New Revision: 284203
URL: https://svnweb.freebsd.org/changeset/base/284203

Log:
  MFC r283602:
  Prevent dounmount() from acting on the freed (although type-stable)
  memory by changing the interface to require the mount point to be
  referenced.
  
  MFC r283629:
  Add missed {}.

Modified:
  stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
  stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
  stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
  stable/10/sys/kern/vfs_mount.c
  stable/10/sys/kern/vfs_subr.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
==============================================================================
--- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c       
Wed Jun 10 02:20:58 2015        (r284202)
+++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c       
Wed Jun 10 02:27:00 2015        (r284203)
@@ -697,6 +697,7 @@ zfsctl_unmount_snap(zfs_snapentry_t *sep
 
        return (0);
 #else  /* !sun */
+       vfs_ref(vn_mountedvfs(svp));
        return (dounmount(vn_mountedvfs(svp), fflags, curthread));
 #endif /* !sun */
 }

Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
==============================================================================
--- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c        
Wed Jun 10 02:20:58 2015        (r284202)
+++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c        
Wed Jun 10 02:27:00 2015        (r284203)
@@ -3481,6 +3481,7 @@ zfs_unmount_snap(const char *snapname)
 #ifdef illumos
        (void) dounmount(vfsp, MS_FORCE, kcred);
 #else
+       vfs_ref(vfsp);
        (void) dounmount(vfsp, MS_FORCE, curthread);
 #endif
        return (0);

Modified: stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
==============================================================================
--- stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c       
Wed Jun 10 02:20:58 2015        (r284202)
+++ stable/10/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c       
Wed Jun 10 02:27:00 2015        (r284203)
@@ -2297,8 +2297,10 @@ bail:
                 * Since we couldn't setup the sa framework, try to force
                 * unmount this file system.
                 */
-               if (vn_vfswlock(zfsvfs->z_vfs->vfs_vnodecovered) == 0)
+               if (vn_vfswlock(zfsvfs->z_vfs->vfs_vnodecovered) == 0) {
+                       vfs_ref(zfsvfs->z_vfs);
                        (void) dounmount(zfsvfs->z_vfs, MS_FORCE, curthread);
+               }
        }
        return (err);
 }

Modified: stable/10/sys/kern/vfs_mount.c
==============================================================================
--- stable/10/sys/kern/vfs_mount.c      Wed Jun 10 02:20:58 2015        
(r284202)
+++ stable/10/sys/kern/vfs_mount.c      Wed Jun 10 02:27:00 2015        
(r284203)
@@ -1128,12 +1128,7 @@ struct unmount_args {
 #endif
 /* ARGSUSED */
 int
-sys_unmount(td, uap)
-       struct thread *td;
-       register struct unmount_args /* {
-               char *path;
-               int flags;
-       } */ *uap;
+sys_unmount(struct thread *td, struct unmount_args *uap)
 {
        struct nameidata nd;
        struct mount *mp;
@@ -1164,8 +1159,10 @@ sys_unmount(td, uap)
                mtx_lock(&mountlist_mtx);
                TAILQ_FOREACH_REVERSE(mp, &mountlist, mntlist, mnt_list) {
                        if (mp->mnt_stat.f_fsid.val[0] == id0 &&
-                           mp->mnt_stat.f_fsid.val[1] == id1)
+                           mp->mnt_stat.f_fsid.val[1] == id1) {
+                               vfs_ref(mp);
                                break;
+                       }
                }
                mtx_unlock(&mountlist_mtx);
        } else {
@@ -1183,8 +1180,10 @@ sys_unmount(td, uap)
                }
                mtx_lock(&mountlist_mtx);
                TAILQ_FOREACH_REVERSE(mp, &mountlist, mntlist, mnt_list) {
-                       if (strcmp(mp->mnt_stat.f_mntonname, pathbuf) == 0)
+                       if (strcmp(mp->mnt_stat.f_mntonname, pathbuf) == 0) {
+                               vfs_ref(mp);
                                break;
+                       }
                }
                mtx_unlock(&mountlist_mtx);
        }
@@ -1202,8 +1201,10 @@ sys_unmount(td, uap)
        /*
         * Don't allow unmounting the root filesystem.
         */
-       if (mp->mnt_flag & MNT_ROOTFS)
+       if (mp->mnt_flag & MNT_ROOTFS) {
+               vfs_rel(mp);
                return (EINVAL);
+       }
        error = dounmount(mp, uap->flags, td);
        return (error);
 }
@@ -1212,10 +1213,7 @@ sys_unmount(td, uap)
  * Do the actual filesystem unmount.
  */
 int
-dounmount(mp, flags, td)
-       struct mount *mp;
-       int flags;
-       struct thread *td;
+dounmount(struct mount *mp, int flags, struct thread *td)
 {
        struct vnode *coveredvp, *fsrootvp;
        int error;
@@ -1235,6 +1233,7 @@ dounmount(mp, flags, td)
                if (coveredvp->v_mountedhere != mp ||
                    coveredvp->v_mountedhere->mnt_gen != mnt_gen_r) {
                        VOP_UNLOCK(coveredvp, 0);
+                       vfs_rel(mp);
                        return (EBUSY);
                }
        }
@@ -1243,13 +1242,14 @@ dounmount(mp, flags, td)
         * original mount is permitted to unmount this filesystem.
         */
        error = vfs_suser(mp, td);
-       if (error) {
+       if (error != 0) {
                if (coveredvp)
                        VOP_UNLOCK(coveredvp, 0);
+               vfs_rel(mp);
                return (error);
        }
 
-       vn_start_write(NULL, &mp, V_WAIT);
+       vn_start_write(NULL, &mp, V_WAIT | V_MNTREF);
        MNT_ILOCK(mp);
        if ((mp->mnt_kern_flag & MNTK_UNMOUNT) != 0 ||
            !TAILQ_EMPTY(&mp->mnt_uppers)) {

Modified: stable/10/sys/kern/vfs_subr.c
==============================================================================
--- stable/10/sys/kern/vfs_subr.c       Wed Jun 10 02:20:58 2015        
(r284202)
+++ stable/10/sys/kern/vfs_subr.c       Wed Jun 10 02:27:00 2015        
(r284203)
@@ -3493,8 +3493,9 @@ vfs_unmountall(void)
         */
        while(!TAILQ_EMPTY(&mountlist)) {
                mp = TAILQ_LAST(&mountlist, mntlist);
+               vfs_ref(mp);
                error = dounmount(mp, MNT_FORCE, td);
-               if (error) {
+               if (error != 0) {
                        TAILQ_REMOVE(&mountlist, mp, mnt_list);
                        /*
                         * XXX: Due to the way in which we mount the root
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to