From vova@vbook.express.ru  Thu May 10 10:01:07 2001
Return-Path: <vova@vbook.express.ru>
Received: from vbook.express.ru (vbook.express.ru [212.24.37.106])
	by hub.freebsd.org (Postfix) with ESMTP id DAE1C37B509
	for <FreeBSD-gnats-submit@freebsd.org>; Thu, 10 May 2001 10:01:04 -0700 (PDT)
	(envelope-from vova@vbook.express.ru)
Received: (from vova@localhost)
	by vbook.express.ru (8.9.3/8.9.3) id VAA11038;
	Thu, 10 May 2001 21:01:20 +0400 (MSD)
	(envelope-from vova)
Message-Id: <200105101701.VAA11038@vbook.express.ru>
Date: Thu, 10 May 2001 21:01:20 +0400 (MSD)
From: vova@express.ru
Reply-To: vova@express.ru
To: FreeBSD-gnats-submit@freebsd.org
Subject: unionfs fixes for 4.x
X-Send-Pr-Version: 3.2

>Number:         27250
>Category:       kern
>Synopsis:       [unionfs] [patch] unionfs filesystem panics in large number of situations
>Confidential:   no
>Severity:       critical
>Priority:       medium
>Responsible:    daichi
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu May 10 10:10:01 PDT 2001
>Closed-Date:    Wed Feb 21 05:21:09 GMT 2007
>Last-Modified:  Wed Feb 21 05:21:09 GMT 2007
>Originator:     Vladimir B. Grebenschikov
>Release:        FreeBSD 4.2-STABLE i386
>Organization:
TSB "Russian Express"
>Environment:

	It was tested on 4.1.1-RELEASE, 4.2-RELEASE, 4.3-RELEASE
	Mount some part of filesystem with mount_union

>Description:

  1. sometimes using mmap'ed files over mount union cause panic 
  2. possible panic when work with sockets/FIFO/dev's on unionfs
  3. panic when no enough rights on current directory when compiled with DIAGNOSTIC
  4. number of vnode leaks
  5. security hole in readdir() - it is possible to go out of the chroot()
     using readdir on unionfs (getdirentries+getdirentries+fchdir)

>How-To-Repeat:

  1. To repeat try to build staroffice port (/usr/ports/editors/staroffice52/) on unionfs.
  2. try to use AF_UNIX sockets over unionfs
  3. build unionfs wiht DIAGNOSTIC and try to do something in directory
     where you have no rights to write
  4. busy software on unionfs with load and observe vnode leak in systat -vm (numvnodes)
  5. when doing getdirentries on unionfs directory it first lists upper
     layer, then lower layer, beetween reading vnode of directory changd
     from upper to lower layer, so just after second getdirentries it is
     possible to do fchdir() on this descriptor to out of chroot().

>Fix:

Patch was tested on 4.1.1-RELEASE, 4.2-RELEASE, 4.3-RELEASE

Index: src/sys/kern/vfs_syscalls.c
===================================================================
RCS file: /home1/cvsroot//freebsd/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.151.2.5.2.3
diff -u -r1.151.2.5.2.3 vfs_syscalls.c
--- src/sys/kern/vfs_syscalls.c	2001/02/27 13:25:48	1.151.2.5.2.3
+++ src/sys/kern/vfs_syscalls.c	2001/05/04 07:35:07
@@ -81,7 +81,9 @@
     const struct timespec *, int));
 static int	usermount = 0;	/* if 1, non-root can mount fs. */
 
+/*
 int (*union_dircheckp) __P((struct proc *, struct vnode **, struct file *));
+*/
 
 SYSCTL_INT(_vfs, OID_AUTO, usermount, CTLFLAG_RW, &usermount, 0, "");
 
@@ -2854,7 +2859,7 @@
 	if ((fp->f_flag & FREAD) == 0)
 		return (EBADF);
 	vp = (struct vnode *)fp->f_data;
-unionread:
+/*unionread:*/
 	if (vp->v_type != VDIR)
 		return (EINVAL);
 	aiov.iov_base = SCARG(uap, buf);
@@ -2921,6 +2926,7 @@
 	VOP_UNLOCK(vp, 0, p);
 	if (error)
 		return (error);
+/*
 	if (SCARG(uap, count) == auio.uio_resid) {
 		if (union_dircheckp) {
 			error = union_dircheckp(p, &vp, fp);
@@ -2940,6 +2946,7 @@
 			goto unionread;
 		}
 	}
+*/
 	error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep),
 	    sizeof(long));
 	p->p_retval[0] = SCARG(uap, count) - auio.uio_resid;
@@ -2980,7 +2987,7 @@
 	if ((fp->f_flag & FREAD) == 0)
 		return (EBADF);
 	vp = (struct vnode *)fp->f_data;
-unionread:
+/*unionread:*/
 	if (vp->v_type != VDIR)
 		return (EINVAL);
 	aiov.iov_base = SCARG(uap, buf);
@@ -2999,6 +3006,7 @@
 	VOP_UNLOCK(vp, 0, p);
 	if (error)
 		return (error);
+/*
 	if (SCARG(uap, count) == auio.uio_resid) {
 		if (union_dircheckp) {
 			error = union_dircheckp(p, &vp, fp);
@@ -3018,6 +3026,7 @@
 			goto unionread;
 		}
 	}
+*/
 	if (SCARG(uap, basep) != NULL) {
 		error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep),
 		    sizeof(long));
Index: src/sys/vm/vm_mmap.c
===================================================================
RCS file: /home1/cvsroot//freebsd/src/sys/vm/vm_mmap.c,v
retrieving revision 1.108.2.2.2.1
diff -u -r1.108.2.2.2.1 vm_mmap.c
--- src/sys/vm/vm_mmap.c	2000/11/03 00:37:39	1.108.2.2.2.1
+++ src/sys/vm/vm_mmap.c	2001/05/04 07:35:07
@@ -78,6 +78,8 @@
 #include <vm/vm_page.h>
 #include <vm/vm_kern.h>
 
+#include <miscfs/union/union.h>
+
 #ifndef _SYS_SYSPROTO_H_
 struct sbrk_args {
 	int incr;
@@ -1074,6 +1076,15 @@
 	/*
 	 * Lookup/allocate object.
 	 */
+        vp = (struct vnode *) handle;
+#if 1
+        if( vp ) {
+                while( vp->v_tag == VT_UNION) {
+                        vp = OTHERVP(vp);
+                }
+                handle = (void *)vp;
+        }
+#endif
 	if (flags & MAP_ANON) {
 		type = OBJT_DEFAULT;
 		/*
@@ -1082,7 +1093,7 @@
 		if (handle == 0)
 			foff = 0;
 	} else {
-		vp = (struct vnode *) handle;
+/*		vp = (struct vnode *) handle; */
 		if (vp->v_type == VCHR) {
 			type = OBJT_DEVICE;
 			handle = (void *)(intptr_t)vp->v_rdev;
Index: src/sys/miscfs/union/union.h
===================================================================
RCS file: /home1/cvsroot//freebsd/src/sys/miscfs/union/union.h,v
retrieving revision 1.17
diff -u -r1.17 union.h
--- src/sys/miscfs/union/union.h	1999/12/29 04:54:48	1.17
+++ src/sys/miscfs/union/union.h	2001/05/04 07:35:07
@@ -97,6 +103,9 @@
 #endif
 };
 
+#define DOCACHE		1	/*union_allocvp argument: default "1"*/
+
+#define UPPERLOCK	0	/* Need uppervp to lock */
 /*
  * XXX UN_ULOCK -	indicates that the uppervp is locked
  *
Index: src/sys/miscfs/union/union_subr.c
===================================================================
RCS file: /home1/cvsroot//freebsd/src/sys/miscfs/union/union_subr.c,v
retrieving revision 1.43
diff -u -r1.43 union_subr.c
--- src/sys/miscfs/union/union_subr.c	1999/12/15 23:02:12	1.43
+++ src/sys/miscfs/union/union_subr.c	2001/05/04 07:35:07
@@ -343,7 +344,9 @@
 {
 	int error;
 	struct union_node *un = 0;
+/*
 	struct vnode *xlowervp = NULLVP;
+*/
 	struct union_mount *um = MOUNTTOUNIONMOUNT(mp);
 	struct proc *p = (cnp) ? cnp->cn_proc : curproc;
 	int hash = 0;
@@ -354,7 +357,10 @@
 		panic("union: unidentifiable allocation");
 
 	if (uppervp && lowervp && (uppervp->v_type != lowervp->v_type)) {
+/*
 		xlowervp = lowervp;
+*/
+		vrele(lowervp);
 		lowervp = NULLVP;
 	}
 
@@ -597,8 +603,10 @@
 	}
 
 out:
+/*
 	if (xlowervp)
 		vrele(xlowervp);
+*/
 
 	if (docache)
 		union_list_unlock(hash);
@@ -1304,6 +1324,7 @@
 /*
  * Module glue to remove #ifdef UNION from vfs_syscalls.c
  */
+#ifdef NEED_BAD_HACK
 static int
 union_dircheck(struct proc *p, struct vnode **vp, struct file *fp)
 {
@@ -1312,6 +1333,9 @@
 	if ((*vp)->v_op == union_vnodeop_p) {
 		struct vnode *lvp;
 
+		if(LOWERVP(*vp) == NULL) {
+			return 0;
+		}
 		lvp = union_dircache(*vp, p);
 		if (lvp != NULLVP) {
 			struct vattr va;
@@ -1347,13 +1371,15 @@
 	}
 	return error;
 }
+#endif
 
+#ifdef NEED_BAD_HACK
 static int
 union_modevent(module_t mod, int type, void *data)
 {
 	switch (type) {
 	case MOD_LOAD:
-		union_dircheckp = union_dircheck;
+		union_dircheckp = union_dircheck; 
 		break;
 	case MOD_UNLOAD:
 		union_dircheckp = NULL;
@@ -1371,3 +1397,4 @@
 };
 
 DECLARE_MODULE(union_dircheck, union_mod, SI_SUB_VFS, SI_ORDER_ANY);
+#endif
Index: src/sys/miscfs/union/union_vfsops.c
===================================================================
RCS file: /home1/cvsroot//freebsd/src/sys/miscfs/union/union_vfsops.c,v
retrieving revision 1.39
diff -u -r1.39 union_vfsops.c
--- src/sys/miscfs/union/union_vfsops.c	1999/12/19 06:07:52	1.39
+++ src/sys/miscfs/union/union_vfsops.c	2001/05/04 07:35:07
@@ -407,7 +412,7 @@
 		VREF(um->um_lowervp);
 
 	error = union_allocvp(vpp, mp, NULLVP, NULLVP, NULL, 
-		    um->um_uppervp, um->um_lowervp, 1);
+		    um->um_uppervp, um->um_lowervp, DOCACHE);
 	UDEBUG(("error %d\n", error));
 	UDEBUG(("union_root2 UPPERVP %p locked = %d\n", um->um_uppervp,
 	    VOP_ISLOCKED(um->um_uppervp, NULL)));
@@ -415,6 +420,22 @@
 	return (error);
 }
 
+static void union_statfs_copy( struct statfs *sbp, struct statfs *mstat, struct statfs *main ) {
+	sbp->f_bsize = mstat->f_bsize;
+        sbp->f_blocks = mstat->f_blocks;
+        sbp->f_bfree = mstat->f_bfree;
+        sbp->f_bavail = mstat->f_bavail;
+        sbp->f_files = mstat->f_files;
+        sbp->f_ffree = mstat->f_ffree;
+        sbp->f_flags = mstat->f_flags;
+        sbp->f_iosize = mstat->f_iosize;
+        if (sbp != main) {
+                sbp->f_type = main->f_type;
+                bcopy(&main->f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid));
+                bcopy(&main->f_mntonname, sbp->f_mntonname, MNAMELEN);
+                bcopy(&main->f_mntfromname, sbp->f_mntfromname, MNAMELEN);
+        }
+}
 static int
 union_statfs(mp, sbp, p)
 	struct mount *mp;
@@ -432,9 +453,22 @@
 	bzero(&mstat, sizeof(mstat));
 
 	if (um->um_lowervp) {
+		if( um->um_lowervp->v_mount == um->um_uppervp->v_mount ) {
+			error = VFS_STATFS(um->um_uppervp->v_mount, &mstat, p);
+			union_statfs_copy(sbp, &mstat, &mp->mnt_stat);
+			return error;
+		}
 		error = VFS_STATFS(um->um_lowervp->v_mount, &mstat, p);
-		if (error)
-			return (error);
+/*uprintf("Lowrvp fsstat return %d\n", error);*/
+		if (error) {
+			error = VFS_STATFS(um->um_uppervp->v_mount, &mstat, p);
+			union_statfs_copy(sbp, &mstat, &mp->mnt_stat);
+			return error;
+		}
+	} else {
+		error = VFS_STATFS(um->um_uppervp->v_mount, &mstat, p);
+		union_statfs_copy(sbp, &mstat, &mp->mnt_stat);
+		return error;
 	}
 
 	/* now copy across the "interesting" information and fake the rest */
@@ -452,6 +486,7 @@
 	sbp->f_ffree = mstat.f_ffree;
 
 	error = VFS_STATFS(um->um_uppervp->v_mount, &mstat, p);
+/*uprintf("Uppervp fsstat return %d\n", error); */
 	if (error)
 		return (error);
 
Index: src/sys/miscfs/union/union_vnops.c
===================================================================
RCS file: /home1/cvsroot//freebsd/src/sys/miscfs/union/union_vnops.c,v
retrieving revision 1.72
diff -u -r1.72 union_vnops.c
--- src/sys/miscfs/union/union_vnops.c	1999/12/15 23:02:14	1.72
+++ src/sys/miscfs/union/union_vnops.c	2001/05/04 07:35:07
@@ -275,6 +275,8 @@
 	return (0);
 }
 
+#define NOOPEN_LOWER 0
+
 static int
 union_lookup(ap)
 	struct vop_lookup_args /* {
@@ -300,6 +302,9 @@
 
 	*ap->a_vpp = NULLVP;
 
+/*if ((cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) {
+printf("lookup: [%.*s] for %d\ncnp->cn_consume = %d\n",cnp->cn_namelen,cnp->cn_nameptr,cnp->cn_nameiop,cnp->cn_consume);
+}*/
 	/*
 	 * Disallow write attemps to the filesystem mounted read-only.
 	 */
@@ -367,7 +372,12 @@
 		    (uppervp ? uppervp->v_usecount : -99),
 		    (uppervp ? VOP_ISLOCKED(uppervp, NULL) : -99)
 		));
-
+/*
+                if(uerror == EACCES) {
+                        error = uerror;
+                        goto out;
+                }
+*/
 		/*
 		 * Disallow write attemps to the filesystem mounted read-only.
 		 */
@@ -538,9 +548,52 @@
 		VOP_UNLOCK(lowervp, 0, p);
 	if (upperdvp)
 		VOP_UNLOCK(upperdvp, 0, p);
-
-	error = union_allocvp(ap->a_vpp, dvp->v_mount, dvp, upperdvp, cnp,
-			      uppervp, lowervp, 1);
+/*
+printf("lookup_end: [%.*s] for %d\n",cnp->cn_namelen,cnp->cn_nameptr,cnp->cn_nameiop);
+*/
+	{
+		struct vnode *tmp;
+		tmp = (uppervp != NULL) ? uppervp : lowervp;
+/*
+printf("vnode = %p\ncnp->cn_nameiop = %d, cnp->cn_name = %.*s, type = %d\nv_usecount = %d\n",
+	tmp,
+        cnp->cn_nameiop, cnp->cn_namelen, cnp->cn_nameptr, tmp->v_type,
+	tmp->v_usecount);
+*/
+		if( (cnp->cn_nameiop == LOOKUP &&
+		     (
+#if NOOPEN_LOWER
+		     tmp->v_type != VREG &&
+#endif
+		     tmp->v_type != VDIR &&
+		     tmp->v_type != VLNK)
+                    )
+#if NOOPEN_LOWER
+		     ||
+		    (tmp->v_type == VREG && (uppervp != NULL) && (
+		     cnp->cn_nameiop == LOOKUP || cnp->cn_nameiop == CREATE))
+#endif
+		   ){
+			*(ap->a_vpp) = tmp;
+                        if(uppervp && lowervp) {
+                                vput(lowervp);
+                                lowervp = 0;
+                        }
+                        if (upperdvp) {
+                                if (upperdvp == tmp) {
+                                        vrele(upperdvp);
+                                } else {
+                                        vput(upperdvp);
+                                }
+                                upperdvp = NULL;
+                        }
+			error = 0;
+		}else{
+			error = union_allocvp(ap->a_vpp, dvp->v_mount,
+				              dvp, upperdvp, cnp,
+				              uppervp, lowervp, 1);
+		}
+	}
 
 	UDEBUG(("Create %p = %p %p refs=%d\n", *ap->a_vpp, uppervp, lowervp, (*ap->a_vpp) ? ((*ap->a_vpp)->v_usecount) : -99));
 
@@ -612,7 +665,8 @@
 	if (cnp->cn_namelen == 1 &&
 	    cnp->cn_nameptr[0] == '.' &&
 	    *ap->a_vpp != dvp) {
-		panic("union_lookup returning . (%p) not same as startdir (%p)", ap->a_vpp, dvp);
+		/*panic("union_lookup returning . (%p) not same as startdir (%p)", *ap->a_vpp, dvp);*/
+		printf("union_lookup returning . (%p) not same as startdir (%p). error = %d\n", *ap->a_vpp, dvp, error);
 	}
 #endif
 
@@ -642,6 +696,9 @@
 	int error = EROFS;
 
 	if ((dvp = union_lock_upper(dun, p)) != NULL) {
+#if	1
+		error = VOP_CREATE(dvp, ap->a_vpp, cnp, ap->a_vap);
+#else
 		struct vnode *vp;
 		struct mount *mp;
 
@@ -654,6 +711,7 @@
 				cnp, vp, NULLVP, 1);
 			UDEBUG(("ALLOCVP-2B FROM %p REFS %d\n", *ap->a_vpp, vp->v_usecount));
 		}
+#endif
 		union_unlock_upper(dvp, p);
 	}
 	return (error);
@@ -672,6 +730,10 @@
 	struct vnode *uppervp;
 	int error = EOPNOTSUPP;
 
+	if (cnp == NULL) {
+		return 0;
+	}
+
 	if ((uppervp = union_lock_upper(un, cnp->cn_proc)) != NULLVP) {
 		error = VOP_WHITEOUT(un->un_uppervp, cnp, ap->a_flags);
 		union_unlock_upper(uppervp, cnp->cn_proc);
@@ -1101,8 +1163,10 @@
 	struct vnode *uppervp;
 	int error;
 
-	if ((uppervp = union_lock_upper(un, p)) == NULLVP)
+	if ((uppervp = union_lock_upper(un, p)) == NULLVP) {
+		printf("un_uppervp: %x\n", un->un_uppervp);
 		panic("union: missing upper layer in write");
+	}
 
 	/*
 	 * Since our VM pages are associated with our vnode rather then
@@ -1318,7 +1382,7 @@
 
 		if (tun->un_uppervp == NULLVP) {
 			vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, p);
-#if 0
+#if UPPERLOCK
 			if (dun->un_uppervp == tun->un_dirvp) {
 				if (dun->un_flags & UN_ULOCK) {
 					dun->un_flags &= ~UN_ULOCK;
@@ -1327,7 +1391,7 @@
 			}
 #endif
 			error = union_copyup(tun, 1, cnp->cn_cred, p);
-#if 0
+#if UPPERLOCK
 			if (dun->un_uppervp == tun->un_dirvp) {
 				vn_lock(dun->un_uppervp,
 					    LK_EXCLUSIVE | LK_RETRY, p);
@@ -1647,12 +1711,35 @@
 	struct proc *p = ap->a_uio->uio_procp;
 	struct vnode *uvp;
 	int error = 0;
+	int save_resid;
 
-	if ((uvp = union_lock_upper(un, p)) != NULLVP) {
+	if ((un->un_uppersz == VNOVAL || un->un_uppersz >= ap->a_uio->uio_offset) && (uvp = union_lock_upper(un, p)) != NULLVP) {
+/*uprintf("readdir un->un_uppersz = %d ap->a_uio->uio_offset = %d\n", un->un_uppersz, ap->a_uio->uio_offset);*/
 		ap->a_vp = uvp;
+		save_resid = ap->a_uio->uio_resid;
 		error = VCALL(uvp, VOFFSET(vop_readdir), ap);
+		if(error) {
+			return(error);
+		}
 		union_unlock_upper(uvp, p);
+		if(un->un_uppersz == VNOVAL || ap->a_uio->uio_offset > un->un_uppersz) {
+			un->un_uppersz = ap->a_uio->uio_offset;
+		}
+		if(ap->a_uio->uio_resid == save_resid) {
+			un->un_uppersz = ap->a_uio->uio_offset;
+		} else {
+			return(0);
+		}
 	}
+	if ((uvp = un->un_lowervp)) {
+		ap->a_uio->uio_offset -= un->un_uppersz;
+		ap->a_vp = uvp;
+		VREF(uvp);
+                vn_lock(uvp, LK_EXCLUSIVE | LK_CANRECURSE | LK_RETRY, p);
+                error = VCALL(uvp, VOFFSET(vop_readdir), ap);
+		vput(uvp);
+		ap->a_uio->uio_offset += un->un_uppersz;
+	}
 	return(error);
 }
 
@@ -1718,7 +1805,7 @@
 		un->un_dircache = 0;
 	}
 
-#if 0
+#if UPPERLOCK
 	if ((un->un_flags & UN_ULOCK) && un->un_uppervp) {
 		un->un_flags &= ~UN_ULOCK;
 		VOP_UNLOCK(un->un_uppervp, 0, p);
@@ -1748,7 +1835,7 @@
 union_lock(ap)
 	struct vop_lock_args *ap;
 {
-#if 0
+#if UPPERLOCK
 	struct vnode *vp = ap->a_vp;
 	struct proc *p = ap->a_p;
 	int flags = ap->a_flags;
@@ -1757,7 +1844,7 @@
 	int error;
 
 	error = vop_stdlock(ap);
-#if 0
+#if UPPERLOCK
 	un = VTOUNION(vp);
 
 	if (error == 0) {
@@ -1800,11 +1887,14 @@
 {
 	struct union_node *un = VTOUNION(ap->a_vp);
 	int error;
+#if UPPERLOCK
+        struct proc *p = ap->a_p;
+#endif
 
 	KASSERT((un->un_uppervp == NULL || un->un_uppervp->v_usecount > 0), ("uppervp usecount is 0"));
 
 	error = vop_stdunlock(ap);
-#if 0
+#if UPPERLOCK
 
 	/*
 	 * If no exclusive locks remain and we are holding an uppervp lock,
>Release-Note:
>Audit-Trail:

From: "Vladimir B. Grebenschikov" <vova@express.ru>
To: freebsd-gnats-submit@FreeBSD.org
Cc:  
Subject: Re: kern/27250: unionfs filesystem panics in large number of situations
Date: Fri, 11 May 2001 20:24:07 +0400 (MSD)

 This patch also fixes panic when try to do mount_union into already
 mounted union partition
 
 --
 TSB Russian Express, Moscow
 Vladimir B. Grebenschikov, vova@express.ru
Responsible-Changed-From-To: freebsd-bugs->bp 
Responsible-Changed-By: kris 
Responsible-Changed-When: Mon May 14 16:37:30 PDT 2001 
Responsible-Changed-Why:  
bp fixed nullfs in -current, so perhaps he will be interested to look at this too 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=27250 

From: Kris Kennaway <kris@obsecurity.org>
To: "Vladimir B. Grebenschikov" <vova@express.ru>
Cc: Kris Kennaway <kris@obsecurity.org>,
	freebsd-gnats-submit@FreeBSD.org
Subject: Re: kern/27250: unionfs filesystem panics in large number of situations
Date: Tue, 15 May 2001 02:11:05 -0700

 --BXVAT5kNtrzKuDFl
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 Content-Transfer-Encoding: quoted-printable
 
 On Tue, May 15, 2001 at 12:54:47PM +0400, Vladimir B. Grebenschikov wrote:
 > Kris Kennaway writes:
 >  > On Fri, May 11, 2001 at 09:30:03AM -0700, Vladimir B. Grebenschikov wr=
 ote:
 >  > > The following reply was made to PR kern/27250; it has been noted by =
 GNATS.
 >  > >=20
 >  > > From: "Vladimir B. Grebenschikov" <vova@express.ru>
 >  > > To: freebsd-gnats-submit@FreeBSD.org
 >  > > Cc: =20
 >  > > Subject: Re: kern/27250: unionfs filesystem panics in large number o=
 f situations
 >  > > Date: Fri, 11 May 2001 20:24:07 +0400 (MSD)
 >  > >=20
 >  > >  This patch also fixes panic when try to do mount_union into already
 >  > >  mounted union partition
 >  >=20
 >  > Did you intend to attach another patch here, or was this a comment
 >  > about your original PR submission?
 > =20
 > It is more description for original PR submition, the patch is result
 > of few months testings so I forgot metion this fix.
 
 Okay, thanks for clarifying.
 
 Kris
 
 --BXVAT5kNtrzKuDFl
 Content-Type: application/pgp-signature
 Content-Disposition: inline
 
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.0.5 (FreeBSD)
 Comment: For info see http://www.gnupg.org
 
 iD8DBQE7APKpWry0BWjoQKURAmlJAJ43YUf2BNBS9BUgLUy883p2IS9/SgCfSYcq
 uKvMZAd6IHTZI+hw1CoVmZ0=
 =Rs4l
 -----END PGP SIGNATURE-----
 
 --BXVAT5kNtrzKuDFl--
State-Changed-From-To: open->analyzed 
State-Changed-By: bp 
State-Changed-When: Tue May 15 03:02:48 PDT 2001 
State-Changed-Why:  
Good work Vladimir! 
The patch needs some cleanup. I'll play with it on -current and 
MFC to -stable. 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=27250 
Responsible-Changed-From-To: bp->freebsd-bugs 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Mon Apr 17 20:59:52 UTC 2006 
Responsible-Changed-Why:  
Reassign at assignee's request due to current lack of time to work on FreeBSD. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=27250 
Responsible-Changed-From-To: freebsd-bugs->daichi 
Responsible-Changed-By: rodrigc 
Responsible-Changed-When: Sun May 28 20:15:10 UTC 2006 
Responsible-Changed-Why:  
daichi is showing interest in unionfs 

http://www.freebsd.org/cgi/query-pr.cgi?pr=27250 
State-Changed-From-To: analyzed->closed 
State-Changed-By: rodrigc 
State-Changed-When: Wed Feb 21 05:20:38 UTC 2007 
State-Changed-Why:  
Patch applies to old unionfs implementation, and not to newer 
unionfs implementation in CURRENT and RELENG_6. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=27250 
>Unformatted:
