From tri@pooh.tky.hut.fi  Fri Apr 25 05:29:36 1997
Received: from vipunen.hut.fi (root@vipunen.hut.fi [130.233.224.20])
          by hub.freebsd.org (8.8.5/8.8.5) with ESMTP id FAA11656
          for <FreeBSD-gnats-submit@freebsd.org>; Fri, 25 Apr 1997 05:29:20 -0700 (PDT)
Received: from pooh.tky.hut.fi (pooh.tky.hut.fi [130.233.23.135]) by vipunen.hut.fi (8.8.5/8.8.2) with ESMTP id PAA125394 for <FreeBSD-gnats-submit@freebsd.org>; Fri, 25 Apr 1997 15:29:12 +0300
Received: by pooh.tky.hut.fi (PAA01865); Fri, 25 Apr 1997 15:29:11 +0300 (EEST)
Message-Id: <199704251229.PAA01865@pooh.tky.hut.fi>
Date: Fri, 25 Apr 1997 15:29:11 +0300 (EEST)
From: tri@iki.fi
Reply-To: tri@iki.fi
To: FreeBSD-gnats-submit@freebsd.org
Cc: tri-bcc@pooh.tky.hut.fi
Subject: Bug in telldir-closedir-opendir-seekdir
X-Send-Pr-Version: 3.2

>Number:         3384
>Category:       kern
>Synopsis:       telldir-seekdir can cause livelock
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Apr 25 05:30:00 PDT 1997
>Closed-Date:    Sun Jul 22 10:25:13 PDT 2001
>Last-Modified:  Sun Jul 22 10:27:52 PDT 2001
>Originator:     Timo J. Rinne
>Release:        FreeBSD 3.0-CURRENT i386
>Organization:
Helsinki University of Technology
>Environment:

	i386 - Pentium 3.0-current 970209 - 9704??

>Description:

	When traversing through directory structure like this pseudocode:

	traverse(d) {
            opendir(d)
            while(e = readdir(d))
                if (directory-p(e))
                    x = telldir(d)
                    closedir(d)
                    traverse(e)
                    opendir(d)
                    seekdir(d, x)
            closedir(d)
        }

	Restoring of the current directory after subtreetraversal
	causes the directory read to start from beginning leading
	to livelock.

>How-To-Repeat:

My colleague Jukka Partanen kindly provided a test program.  
Gets stuck when ran in directory with ordinary files and subdirectories.
Works in NetBSD and Linux, gets stuck in FreeBSD.

>Fix:
	
	Sorry.  No time to debug.  We use different OS in our
	production system.
>Release-Note:
>Audit-Trail:

From: Doug Rabson <dfr@nlsystems.com>
To: tri@iki.fi
Cc: FreeBSD-gnats-submit@freebsd.org, tri-bcc@pooh.tky.hut.fi,
        GNATS Management <gnats@hub.freebsd.org>, freebsd-bugs@hub.freebsd.org
Subject: Re: kern/3384: Bug in telldir-closedir-opendir-seekdir
Date: Fri, 25 Apr 1997 15:07:18 +0100 (BST)

 You can't use the results of telldir after the directory has been closed.
 The manpage for seekdir clearly states this.
 
 --
 Doug Rabson				Mail:  dfr@nlsystems.com
 Nonlinear Systems Ltd.			Phone: +44 181 951 1891
 

From: Bill Fenner <fenner@parc.xerox.com>
To: freebsd-gnats-submit@freebsd.org
Cc:  Subject: Re: kern/3384: telldir-seekdir can cause livelock
Date: Sat, 5 Jul 1997 13:05:24 PDT

 Actually, the relevant portion of the seekdir man page is probably
 
 			 It is safe to use a previous telldir() val-
      ue immediately after a call to opendir() and before any calls to
      readdir().
 
 which is what the test program does, so either the man page or the
 implementation is wrong.
 
 The readdir() man page doesn't happen to mention that the storage that
 readdir() returns will be freed when you call closedir(); this is not
 the case on other systems so should perhaps be documented (especially
 since it's the cause of one of the bugs in the test program).
 
   Bill
State-Changed-From-To: open->feedback 
State-Changed-By: mike 
State-Changed-When: Sat Jul 21 23:04:06 PDT 2001 
State-Changed-Why:  

Does this problem still occur in newer versions of FreeBSD, 
such as 4.3-RELEASE? 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=3384 
State-Changed-From-To: feedback->closed 
State-Changed-By: mike 
State-Changed-When: Sun Jul 22 10:25:13 PDT 2001 
State-Changed-Why:  

This test program has bugs.  Namely one cannot depend on telldir(3) 
after the directory has been closed with closedir(3) because the 
data will have been free(3)'d by then. 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=3384 
>Unformatted:
 >>>>>>>>>>>>>>>>>>   C U T   H E R E   >>>>>>>>>>>>>>>>>>
 
 /*
  *
  * dirtest.c
  *
  * Author: Jukka Partanen <jukka.partanen@research.nokia.com>
  *
  * Copyright (c) 1997 Nokia Research Center
  * All rights reserved
  *
  * Created      : Thu Apr 24 14:53:03 1997 partanen
  * Last modified: Fri Apr 25 09:47:13 1997 partanen
  *
  * $Id$
  *
  */
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <dirent.h>
 #include <limits.h>
 
 static int process_dir(int namelen);
 
 static char file[PATH_MAX+1];
 
 int main(int argc, char *argv[])
 {
     char *name = argc > 1 ? argv[1] : ".";
     int   namelen;
     
     strcpy(file, name);
     namelen = strlen(file);
     if (namelen && file[namelen - 1] == '/')
         namelen--;
     return process_dir(namelen);
 }
 
 static int process_dir(int namelen)
 {
     long dirpos;
     DIR *dirp;
     struct dirent *dp;
     struct stat statbuf;
 
     dirp = opendir(file);
     if (!dirp) {
         perror(file);
         return 1;
     }
     while ((dp = readdir(dirp)) != NULL) {
         file[namelen] = '/';
         strcpy(file + namelen + 1, dp->d_name);
         if (stat(file, &statbuf) < 0) {
             perror(file);
         } else {
             printf("%s\n", file);
             if ((statbuf.st_mode & S_IFDIR) &&
                 strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) {
                 dirpos = telldir(dirp);
                 closedir(dirp);
                 process_dir(namelen + strlen(dp->d_name) + 1);
                 file[namelen] = '\0';
                 dirp = opendir(file);
                 if (!dirp) {
                     perror(file);
                     return 1;
                 }
                 seekdir(dirp, dirpos);
             }
         }
         file[namelen] = '\0';
     }
     closedir(dirp);
     return 0;
 }
 
 >>>>>>>>>>>>>>>>>>   C U T   H E R E   >>>>>>>>>>>>>>>>>>
 
