From eugen@www.svzserv.kemerovo.su  Wed Jun  6 20:52:18 2001
Return-Path: <eugen@www.svzserv.kemerovo.su>
Received: from www.svzserv.kemerovo.su (www.svzserv.kemerovo.su [213.184.65.80])
	by hub.freebsd.org (Postfix) with ESMTP id 526F237B401
	for <FreeBSD-gnats-submit@freebsd.org>; Wed,  6 Jun 2001 20:52:16 -0700 (PDT)
	(envelope-from eugen@www.svzserv.kemerovo.su)
Received: (from eugen@localhost)
	by www.svzserv.kemerovo.su (8.9.3/8.9.3) id LAA38904;
	Thu, 7 Jun 2001 11:52:13 +0800 (KRAST)
	(envelope-from eugen)
Message-Id: <200106070352.LAA38904@www.svzserv.kemerovo.su>
Date: Thu, 7 Jun 2001 11:52:13 +0800 (KRAST)
From: eugen@grosbein.pp.ru
Reply-To: eugen@www.svzserv.kemerovo.su
To: FreeBSD-gnats-submit@freebsd.org
Subject: FreeBSD-SA-01:40
X-Send-Pr-Version: 3.2

>Number:         27922
>Category:       bin
>Synopsis:       FreeBSD-SA-01:40
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    imp
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jun 06 21:00:16 PDT 2001
>Closed-Date:    Thu Oct 11 05:08:57 PDT 2001
>Last-Modified:  Thu Oct 11 05:09:28 PDT 2001
>Originator:     Eugene Grosbein
>Release:        FreeBSD 3.5-STABLE i386
>Organization:
ISP Svyaz-Service
>Environment:
FreeBSD 3.5-STABLE i386

>Description:

A patch in FreeBSD Security Advisory FreeBSD-SA-01:40 does not apply to
3.5-STABLE. Here is a path from advisory adopted for RELENG_3 at the time of
advisory issue.

>How-To-Repeat:

	Exploit has been posted to security@freebsd.org mailing list.

>Fix:

Here is a patch for 3.5-STABLE build 10 May 2001.
How to apply:

# cd /usr/src/lib/libc/gen
# patch </path/to/ftp.3S.patch
# cd ..
# make depend && make all install
# cd /usr/src/lib/libc_r
# make depend && make all install
# cd /usr/src/bin/chmod
# make depend && make all install
# cd /usr/src/bin/cp
# make depend && make all install
# cd /usr/src/bin/ls
# make depend && make all install
# cd /usr/src/bin/pax
# make depend && make all install
# cd /usr/src/bin/rm
# make depend && make all install
# cd /usr/src/usr.bin/chflags
# make depend && make all install
# cd /usr/src/usr.bin/du
# make depend && make all install
# cd /usr/src/usr.bin/find
# make depend && make all install
# cd /usr/src/libexec/ftpd
# make depend && make all install
# cd /usr/src/usr.sbin/chmod
# make depend && make all install
# cd /usr/src/usr.sbin/ckdist
# make depend && make all install
# cd /usr/src/usr.sbin/ctm
# make depend && make all install
# cd /usr/src/usr.sbin/mtree
# make depend && make all install
# cd /usr/src/usr.sbin/pkg_install
# make depend && make all install

Patch:

--- fts.c.orig	Sat Dec 25 15:29:45 1999
+++ fts.c	Thu Jun  7 11:08:07 2001
@@ -61,7 +61,7 @@
 static int	 fts_palloc __P((FTS *, size_t));
 static FTSENT	*fts_sort __P((FTS *, FTSENT *, int));
 static u_short	 fts_stat __P((FTS *, FTSENT *, int));
-static int	 fts_safe_changedir __P((FTS *, FTSENT *, int));
+static int	 fts_safe_changedir __P((FTS *, FTSENT *, int, char *));
 
 #define	ISDOT(a)	(a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
 
@@ -69,7 +69,6 @@
 #define	ISSET(opt)	(sp->fts_options & (opt))
 #define	SET(opt)	(sp->fts_options |= (opt))
 
-#define	CHDIR(sp, path)	(!ISSET(FTS_NOCHDIR) && chdir(path))
 #define	FCHDIR(sp, fd)	(!ISSET(FTS_NOCHDIR) && fchdir(fd))
 
 /* fts_build flags */
@@ -273,6 +272,7 @@
 fts_read(sp)
 	register FTS *sp;
 {
+	struct stat sb;
 	register FTSENT *p, *tmp;
 	register int instr;
 	register char *t;
@@ -349,7 +349,7 @@
 		 * FTS_STOP or the fts_info field of the node.
 		 */
 		if (sp->fts_child) {
-			if (fts_safe_changedir(sp, p, -1)) {
+			if (fts_safe_changedir(sp, p, -1, p->fts_accpath)) {
 				p->fts_errno = errno;
 				p->fts_flags |= FTS_DONTCHDIR;
 				for (p = sp->fts_child; p; p = p->fts_link)
@@ -446,11 +446,10 @@
 			return (NULL);
 		}
 		(void)close(p->fts_symfd);
-	} else if (!(p->fts_flags & FTS_DONTCHDIR)) {
-		if (CHDIR(sp, "..")) {
-			SET(FTS_STOP);
-			return (NULL);
-		}
+	} else if (!(p->fts_flags & FTS_DONTCHDIR) &&
+ 		   fts_safe_changedir(sp, p->fts_parent, -1, "..")) {
+ 		SET(FTS_STOP);
+ 		return (NULL);
 	}
 	p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP;
 	return (sp->fts_cur = p);
@@ -637,7 +636,7 @@
 	 */
 	cderrno = 0;
 	if (nlinks || type == BREAD) {
-		if (fts_safe_changedir(sp, cur, dirfd(dirp))) {
+		if (fts_safe_changedir(sp, cur, dirfd(dirp), NULL)) {
 			if (nlinks && type == BREAD)
 				cur->fts_errno = errno;
 			cur->fts_flags |= FTS_DONTCHDIR;
@@ -803,7 +802,8 @@
 	 */
 	if (descend && (type == BCHILD || !nitems) &&
 	    (cur->fts_level == FTS_ROOTLEVEL ?
-	    FCHDIR(sp, sp->fts_rfd) : CHDIR(sp, ".."))) {
+	    FCHDIR(sp, sp->fts_rfd) :
+	    fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) {
 		cur->fts_info = FTS_ERR;
 		SET(FTS_STOP);
 		return (NULL);
@@ -1075,10 +1075,11 @@
  * Assumes p->fts_dev and p->fts_ino are filled in.
  */
 static int
-fts_safe_changedir(sp, p, fd)
+fts_safe_changedir(sp, p, fd, path)
 	FTS *sp;
 	FTSENT *p;
 	int fd;
+	char *path;
 {
 	int ret, oerrno, newfd;
 	struct stat sb;
@@ -1086,7 +1087,7 @@
 	newfd = fd;
 	if (ISSET(FTS_NOCHDIR))
 		return (0);
-	if (fd < 0 && (newfd = open(p->fts_accpath, O_RDONLY, 0)) < 0)
+	if (fd < 0 && (newfd = _open(path, O_RDONLY, 0)) < 0)
 		return (-1);
 	if (fstat(newfd, &sb)) {
 		ret = -1;
>Release-Note:
>Audit-Trail:

From: "Sergey N. Voronkov" <serg@tmn.ru>
To: eugen@www.svzserv.kemerovo.su
Cc: FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: bin/27922: FreeBSD-SA-01:40
Date: Thu, 7 Jun 2001 11:27:14 +0600

 On Thu, Jun 07, 2001 at 11:52:13AM +0800, eugen@grosbein.pp.ru wrote:
 > >Environment:
 > FreeBSD 3.5-STABLE i386
 > 
 > >Description:
 > 
 > A patch in FreeBSD Security Advisory FreeBSD-SA-01:40 does not apply to
 > 3.5-STABLE. Here is a path from advisory adopted for RELENG_3 at the time of
 > advisory issue.
 > 
 > >How-To-Repeat:
 > 
 > 	Exploit has been posted to security@freebsd.org mailing list.
 > 
 
 RELENG_3 branch declared to support ONLY fixes of remote exploits (see
 http://docs.freebsd.org/cgi/getmsg.cgi?fetch=3320+0+archive/2001/
 freebsd-announce/20010513.freebsd-announce).
 
 Bye,
 
 Serg N. Voronkov.

From: Eugene Grosbein <eugen@svzserv.kemerovo.su>
To: "Sergey N. Voronkov" <serg@tmn.ru>
Cc: eugen@www.svzserv.kemerovo.su, FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: bin/27922: FreeBSD-SA-01:40
Date: Thu, 07 Jun 2001 13:47:33 +0800

 > > A patch in FreeBSD Security Advisory FreeBSD-SA-01:40 does not apply to
 > > 3.5-STABLE. Here is a path from advisory adopted for RELENG_3 at the time of
 > > advisory issue.
 > >
 > > >How-To-Repeat:
 > >
 > >       Exploit has been posted to security@freebsd.org mailing list.
 > >
 > 
 > RELENG_3 branch declared to support ONLY fixes of remote exploits (see
 > http://docs.freebsd.org/cgi/getmsg.cgi?fetch=3320+0+archive/2001/
 > freebsd-announce/20010513.freebsd-announce).
 
 I know. It was said, if someone will supply patches for RELENG_3, they will
 be consideted, so I corrected the patch.
 
 Eugene Grosbein
Responsible-Changed-From-To: freebsd-bugs->security-officer 
Responsible-Changed-By: roam 
Responsible-Changed-When: Wed Jun 6 23:03:54 PDT 2001 
Responsible-Changed-Why:  
Let's see if this works :) 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=27922 
Responsible-Changed-From-To: security-officer->imp 
Responsible-Changed-By: imp 
Responsible-Changed-When: Thu Jun 7 00:15:54 MDT 2001 
Responsible-Changed-Why:  
Since someone went to the trouble of doing the patch, I'll try it with my 3.5 
tree and commit it if things compile after auditing the contents of the 
patch. 

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

From: Eugene Grosbein <eugen@www.svzserv.kemerovo.su>
To: freebsd-gnats-submit@FreeBSD.org
Cc: imp@FreeBSD.org
Subject: Re: bin/27922: FreeBSD-SA-01:40
Date: Wed, 13 Jun 2001 16:35:06 +0700

 > @@ -1086,7 +1087,7 @@
 >              newfd = fd;
 >              if (ISSET(FTS_NOCHDIR))
 >                      return (0);
 >      -       if (fd < 0 && (newfd = open(p->fts_accpath, O_RDONLY, 0)) < 0)
 >      +       if (fd < 0 && (newfd = _open(path, O_RDONLY, 0)) < 0)
 >                      return (-1);
 >              if (fstat(newfd, &sb)) {
 >                      ret = -1;
 
 I'm very sorry but this patch breaks libc_r on 3.5-STABLE.
 The use of missing _open() is incorrect here, it needs to be changed back
 to open(). With this one-line change the patch looks like this:
 
 --- fts.c.orig  Sat Dec 25 15:29:45 1999
 +++ fts.c       Wed Jun 13 16:17:28 2001
 @@ -61,7 +61,7 @@
  static int      fts_palloc __P((FTS *, size_t));
  static FTSENT  *fts_sort __P((FTS *, FTSENT *, int));
  static u_short  fts_stat __P((FTS *, FTSENT *, int));
 -static int      fts_safe_changedir __P((FTS *, FTSENT *, int));
 +static int      fts_safe_changedir __P((FTS *, FTSENT *, int, char *));
  
  #define        ISDOT(a)        (a[0] == '.' && (!a[1] || (a[1] == '.' &&
 !a[2])))
  
 @@ -69,7 +69,6 @@
  #define        ISSET(opt)      (sp->fts_options & (opt))
  #define        SET(opt)        (sp->fts_options |= (opt))
  
 -#define        CHDIR(sp, path) (!ISSET(FTS_NOCHDIR) && chdir(path))
  #define        FCHDIR(sp, fd)  (!ISSET(FTS_NOCHDIR) && fchdir(fd))
  
  /* fts_build flags */
 @@ -273,6 +272,7 @@
  fts_read(sp)
         register FTS *sp;
  {
 +       struct stat sb;
         register FTSENT *p, *tmp;
         register int instr;
         register char *t;
 @@ -349,7 +349,7 @@
                  * FTS_STOP or the fts_info field of the node.
                  */
                 if (sp->fts_child) {
 -                       if (fts_safe_changedir(sp, p, -1)) {
 +                       if (fts_safe_changedir(sp, p, -1, p->fts_accpath)) {
                                 p->fts_errno = errno;
                                 p->fts_flags |= FTS_DONTCHDIR;
                                 for (p = sp->fts_child; p; p = p->fts_link)
 @@ -446,11 +446,10 @@
                         return (NULL);
                 }
                 (void)close(p->fts_symfd);
 -       } else if (!(p->fts_flags & FTS_DONTCHDIR)) {
 -               if (CHDIR(sp, "..")) {
 -                       SET(FTS_STOP);
 -                       return (NULL);
 -               }
 +       } else if (!(p->fts_flags & FTS_DONTCHDIR) &&
 +                  fts_safe_changedir(sp, p->fts_parent, -1, "..")) {
 +               SET(FTS_STOP);
 +               return (NULL);
         }
         p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP;
         return (sp->fts_cur = p);
 @@ -637,7 +636,7 @@
          */
         cderrno = 0;
         if (nlinks || type == BREAD) {
 -               if (fts_safe_changedir(sp, cur, dirfd(dirp))) {
 +               if (fts_safe_changedir(sp, cur, dirfd(dirp), NULL)) {
                         if (nlinks && type == BREAD)
                                 cur->fts_errno = errno;
                         cur->fts_flags |= FTS_DONTCHDIR;
 @@ -803,7 +802,8 @@
          */
         if (descend && (type == BCHILD || !nitems) &&
             (cur->fts_level == FTS_ROOTLEVEL ?
 -           FCHDIR(sp, sp->fts_rfd) : CHDIR(sp, ".."))) {
 +           FCHDIR(sp, sp->fts_rfd) :
 +           fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) {
                 cur->fts_info = FTS_ERR;
                 SET(FTS_STOP);
                 return (NULL);
 @@ -1075,10 +1075,11 @@
   * Assumes p->fts_dev and p->fts_ino are filled in.
   */
  static int
 -fts_safe_changedir(sp, p, fd)
 +fts_safe_changedir(sp, p, fd, path)
         FTS *sp;
         FTSENT *p;
         int fd;
 +       char *path;
  {
         int ret, oerrno, newfd;
         struct stat sb;
 @@ -1086,7 +1087,7 @@
         newfd = fd;
         if (ISSET(FTS_NOCHDIR))
                 return (0);
 -       if (fd < 0 && (newfd = open(p->fts_accpath, O_RDONLY, 0)) < 0)
 +       if (fd < 0 && (newfd = open(path, O_RDONLY, 0)) < 0)
                 return (-1);
         if (fstat(newfd, &sb)) {
                 ret = -1;
 
 Eugene Grosbein
State-Changed-From-To: open->closed 
State-Changed-By: fjoe 
State-Changed-When: Thu Oct 11 05:08:57 PDT 2001 
State-Changed-Why:  
fix committed to RELENG_3 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=27922 
>Unformatted:
