Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 28 Jul 1999 20:40:02 -0700 (PDT)
From:      Bruce Evans <bde@zeta.org.au>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: kern/12855: panic:softdep_flushfiles:looping, caused by user creating deep directory structure
Message-ID:  <199907290340.UAA59966@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/12855; it has been noted by GNATS.

From: Bruce Evans <bde@zeta.org.au>
To: freebsd-gnats-submit@FreeBSD.ORG, kfarmer@sympatico.ca
Cc:  
Subject: Re: kern/12855: panic:softdep_flushfiles:looping, caused by user creating deep directory structure
Date: Thu, 29 Jul 1999 13:32:01 +1000

 >>Description:
 >if a user creates a very deep directory structure (eg, /usr/home/guest/tmp/tmp/tmp/tmp/tmp/....)
 >Then umounting the filesystem causes: panic:softdep_flushfiles:looping.
 >also: rm -rf cannot remove the directory structure, claims 'directory not empty'
 
 Here is a possible fix for rm(1) and find(1), etc.  Don't commit it verbatim;
 the changes in fts.c are mostly for debugging.
 
 fts.c is just buggy.  It creates garbage pointers.  rm.c was broken
 in rev.1.2 by applying an apparently obsolete (and wrong) patch from
 FreeBSD-1.1.5.  POSIX.1 requires rm(1) and find(1) to work on arbitrarily
 deep directories; therefore they must use chdir(2) to reduce path lengths
 and they must not use FTS_NOCHDIR.
 
 Burce
 
 diff -c2 src/bin/rm/rm.c~ src/bin/rm/rm.c
 *** src/bin/rm/rm.c~	Sun May 30 17:04:01 1999
 --- src/bin/rm/rm.c	Sun May 30 17:04:04 1999
 ***************
 *** 160,164 ****
   #define	SKIPPED	1
   
 ! 	flags = FTS_PHYSICAL | FTS_NOCHDIR;
   	if (!needstat)
   		flags |= FTS_NOSTAT;
 --- 160,164 ----
   #define	SKIPPED	1
   
 ! 	flags = FTS_PHYSICAL;
   	if (!needstat)
   		flags |= FTS_NOSTAT;
 diff -c2 src/lib/libc/gen/fts.c~ src/lib/libc/gen/fts.c
 *** src/lib/libc/gen/fts.c~	Thu Sep 17 14:24:03 1998
 --- src/lib/libc/gen/fts.c	Thu May  6 14:15:17 1999
 ***************
 *** 964,967 ****
 --- 964,985 ----
   }
   
 + static void
 + ADJUST(p, addr)
 + 	FTSENT *p;
 + 	void *addr;
 + {
 + 	if ((p)->fts_accpath >= (p)->fts_path &&			
 + 	    (p)->fts_accpath < (p)->fts_path + (p)->fts_pathlen) {
 + 		if (p->fts_accpath != p->fts_path)
 + 			errx(1, "fts ADJUST: accpath %p path %p",
 + 			    p->fts_accpath, p->fts_path);
 + 		if (p->fts_level != 0)
 + 			errx(1, "fts ADJUST: level %d not 0", p->fts_level);
 + 		(p)->fts_accpath =					
 + 		    (char *)addr + ((p)->fts_accpath - (p)->fts_path);	
 + 	}
 + 	(p)->fts_path = addr;						
 + }
 + 
   /*
    * When the path is realloc'd, have to fix all of the pointers in structures
 ***************
 *** 975,990 ****
   	FTSENT *p;
   
 ! #define	ADJUST(p) {							\
 ! 	(p)->fts_accpath =						\
 ! 	    (char *)addr + ((p)->fts_accpath - (p)->fts_path);		\
   	(p)->fts_path = addr;						\
   }
   	/* Adjust the current set of children. */
   	for (p = sp->fts_child; p; p = p->fts_link)
 ! 		ADJUST(p);
   
   	/* Adjust the rest of the tree. */
   	for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {
 ! 		ADJUST(p);
   		p = p->fts_link ? p->fts_link : p->fts_parent;
   	}
 --- 993,1008 ----
   	FTSENT *p;
   
 ! #define	ADJUST1(p) {							\
 ! 	if ((p)->fts_accpath == (p)->fts_path)				\
 ! 		(p)->fts_accpath = (addr);				\
   	(p)->fts_path = addr;						\
   }
   	/* Adjust the current set of children. */
   	for (p = sp->fts_child; p; p = p->fts_link)
 ! 		ADJUST(p, addr);
   
   	/* Adjust the rest of the tree. */
   	for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {
 ! 		ADJUST(p, addr);
   		p = p->fts_link ? p->fts_link : p->fts_parent;
   	}
 


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199907290340.UAA59966>