Subject: [stas@SONET.CRIMEA.UA: Re: fts...(improved patch)]
To: None <tech-userlevel@NetBSD.org>
From: Manuel Bouyer <bouyer@antioche.lip6.fr>
List: tech-userlevel
Date: 05/14/1999 22:25:58
-----Forwarded message from Stas Kisel <stas@SONET.CRIMEA.UA>-----

	by antioche.lip6.fr (8.8.8/8.8.5) with ESMTP id TAA10753
	for <bouyer@ANTIOCHE.lip6.fr>; Fri, 14 May 1999 19:19:12 +0200 (MEST)
          by isis.lip6.fr (8.8.8/jtpda-5.2.9.1+lip6) with ESMTP id TAA11283
          for <bouyer@ANTIOCHE.LIP6.FR>; Fri, 14 May 1999 19:18:51 +0200 (MET DST)
          spool id 908565 for BUGTRAQ@NETSPACE.ORG; Fri, 14 May 1999 17:04:34
          +0000
Approved-By: aleph1@UNDERGROUND.ORG
          netspace.org (8.8.7/8.8.7) with ESMTP id HAA01109 for
          <bugtraq@netspace.org>; Fri, 14 May 1999 07:37:03 -0400
          Fri, 14 May 1999 14:37:03 +0400 (MSD)
Message-ID: <199905141037.OAA14127@sonet.crimea.ua>
Date: 	Fri, 14 May 1999 14:37:03 +0400
Reply-To: Stas Kisel <stas@SONET.CRIMEA.UA>
Sender: Bugtraq List <BUGTRAQ@netspace.org>
From: Stas Kisel <stas@SONET.CRIMEA.UA>
Subject:      Re: fts...(improved patch)
To: BUGTRAQ@netspace.org
In-Reply-To:  <Pine.LNX.4.05.9905140429230.22741-100000@demerol.darkridge.com>

> From: Jordan Ritter <jpr5@darkridge.com>
> OpenBSD definitely has the same problem.  last thing I remember thinking
> was that it was dying because realloc() was failing (as the fts stuff
> realloc()'s memory as the path grows) ..

fts realloc (pathlen+~1000b) of memory only, so realloc succeds.
The bug is in the adjusting pointers after realloc().

Next day after sending patch I've found another circumstanses that
triggered similar bug in fts.
This time some pointers were adjusted which did not belong to realloc()-ed
memory chunk.

Improved patch is below. Sorry for inconvenience.
Probably there are some similar bugs in fts code or patch. Please let me
know if you'll see any.

\bye
Stas

----------------------------- patch ----------------------------------
--- /usr/src/lib/libc/gen/fts.c.orig	Tue May 11 13:37:49 1999
+++ /usr/src/lib/libc/gen/fts.c	Fri May 14 14:02:58 1999
@@ -740,8 +740,26 @@
 	 * If had to realloc the path, adjust the addresses for the rest
 	 * of the tree.
 	 */
-	if (adjaddr)
+	if (adjaddr){
 		fts_padjust(sp, adjaddr);
+		/* Adjust the list, because we want to return it robust. */
+/* fix p->fts_path and p->fts_accpath
+   p->fts_accpath can be:
+	either cur->fts_path	(adjust, because cur is already adjusted)
+	either p->fts_path	(adjust)
+	either p->fts_name	(do not adjust)
+   I'm also almost sure that in first case cur->fts_path=p->fts_path...
+*/
+#define	ADJUST1(p) if((p)->fts_path != adjaddr){	\
+	if((p)->fts_accpath != (p)->fts_name){		\
+		(p)->fts_accpath =			\
+			(char *)adjaddr + ((p)->fts_accpath - (p)->fts_path);\
+	}						\
+	(p)->fts_path = adjaddr;			\
+}
+		for (p = head; p; p = p->fts_link)
+			ADJUST1(p);
+	}

 	/*
 	 * If not changing directories, reset the path back to original
@@ -974,18 +992,20 @@
 {
 	FTSENT *p;

-#define	ADJUST(p) {							\
-	(p)->fts_accpath =						\
-	    (char *)addr + ((p)->fts_accpath - (p)->fts_path);		\
+#define	ADJUST2(p) {							\
+	if((p)->fts_accpath != (p)->fts_name){				\
+		(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);
+		ADJUST2(p);

 	/* Adjust the rest of the tree. */
 	for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {
-		ADJUST(p);
+		ADJUST2(p);
 		p = p->fts_link ? p->fts_link : p->fts_parent;
 	}
 }
----------------------------- /patch ----------------------------------

-----End of forwarded message-----

-- 
--
Manuel Bouyer, LIP6, Universite Paris VI.           Manuel.Bouyer@lip6.fr
     {Net,Free}BSD: 22 ans d'experience feront toujours la difference
--