From nobody@FreeBSD.org  Mon Sep 17 08:34:32 2001
Return-Path: <nobody@FreeBSD.org>
Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21])
	by hub.freebsd.org (Postfix) with ESMTP id 433D037B405
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 17 Sep 2001 08:34:32 -0700 (PDT)
Received: (from nobody@localhost)
	by freefall.freebsd.org (8.11.4/8.11.4) id f8HFYWf70187;
	Mon, 17 Sep 2001 08:34:32 -0700 (PDT)
	(envelope-from nobody)
Message-Id: <200109171534.f8HFYWf70187@freefall.freebsd.org>
Date: Mon, 17 Sep 2001 08:34:32 -0700 (PDT)
From: Jim Bauer <jfbauer@nfr.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: readdir_r() SEGV on large directories
X-Send-Pr-Version: www-1.0

>Number:         30631
>Category:       misc
>Synopsis:       readdir_r() SEGV on large directories
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Sep 17 08:40:00 PDT 2001
>Closed-Date:    Tue Feb 26 14:58:28 PST 2002
>Last-Modified:  Tue Feb 26 14:59:36 PST 2002
>Originator:     Jim Bauer
>Release:        4.2-RELEASE and 4.3-RELEASE
>Organization:
NFR Security Inc
>Environment:
FreeBSD heraus.nfr.net 4.2-RELEASE FreeBSD 4.2-RELEASE #0: Wed Sep  5 10:02:48 EDT 2001     jfbauer@heraus.nfr.net:/usr/src/sys/compile/GENERIC.SMP  i386

>Description:
Under some circumstances, readdir_r() tries to memcpy too much
data from the buffer opendir() malloced thus reading beyond the
end of the buffer.  The problem only seems to occur if "-pthread"
is given on the compile command line.
>How-To-Repeat:
/*
 * To repeat:
 * cc .... -pthread
 *
 * d="d.$$"; mkdir $d
 * i=1; while [ $i -lt 245 ]; do touch $d/f.$i; i=`expr $i + 1`; done
 *
 * ./a.out $d
 *
 * When I run this it outputs....
 * file = f.1
 * file = f.2
 * ...
 * file = f.240
 * Segmentation fault (core dumped)
 */

#include <stdio.h>
#include <dirent.h> 


int main(int argc, char **argv) {
  DIR *dir;
  struct dirent entry;
  struct dirent *result;
  char *dirname = ".";

  if (argc > 2) {
    fprintf(stderr, "Usage %s [dir]\n", argv[0]);
    exit(1);
  }

  if (argc == 2)
    dirname = argv[1];


  dir = opendir(dirname);
  if (dir == NULL) {
    perror("opendir");
    exit(1);
  }

  while (readdir_r(dir, &entry, &result) == 0 && result != NULL) {
    printf("file = %s\n", entry.d_name);
  }

}

>Fix:
Changing the memcpy() in readdir_r() to only copy d_namlen bytes
instead of sizeof(struct dirent) should fix the problem, but this
has not been tested.
>Release-Note:
>Audit-Trail:

From: Jim Bauer <jfbauer@nfr.com>
To: freebsd-gnats-submit@FreeBSD.org, jfbauer@nfr.com
Cc:  
Subject: Re: misc/30631: readdir_r() SEGV on large directories
Date: Mon, 17 Sep 2001 14:21:48 -0400

 Correction to suggested fix.
 
   memcpy(entry, dp, (unsigned) &dp->d_name - (unsigned)dp + dp->d_namlen
 + 1);
 
 -- 
 Jim Bauer, jfbauer@nfr.com
 NFR Security, Inc.  240-747-3405

From: Kris Kennaway <kris@obsecurity.org>
To: Jim Bauer <jfbauer@nfr.com>
Cc: freebsd-gnats-submit@FreeBSD.org
Subject: Re: misc/30631: readdir_r() SEGV on large directories
Date: Sun, 23 Sep 2001 16:47:50 -0700

 On Mon, Sep 17, 2001 at 11:30:04AM -0700, Jim Bauer wrote:
 > The following reply was made to PR misc/30631; it has been noted by GNATS.
 > 
 > From: Jim Bauer <jfbauer@nfr.com>
 > To: freebsd-gnats-submit@FreeBSD.org, jfbauer@nfr.com
 > Cc:  
 > Subject: Re: misc/30631: readdir_r() SEGV on large directories
 > Date: Mon, 17 Sep 2001 14:21:48 -0400
 > 
 >  Correction to suggested fix.
 >  
 >    memcpy(entry, dp, (unsigned) &dp->d_name - (unsigned)dp + dp->d_namlen
 >  + 1);
 
 Please submit an updated patch.
 
 Kris

From: "Carlos F. A. Paniago" <pan@cnpm.embrapa.br>
To: freebsd-gnats-submit@FreeBSD.org, jfbauer@nfr.com
Cc:  
Subject: Re: misc/30631: readdir_r() SEGV on large directories
Date: Tue, 23 Oct 2001 11:48:43 -0200

 This behavior (bug) still in FreebSD 4.4. It's is dumping core in
 svtest, part of openoffice. Please someone look at that and fix it.
 
     Paniago
 
 

From: "Carlos F. A. Paniago" <pan@cnpm.embrapa.br>
To: freebsd-gnats-submit@FreeBSD.org, jfbauer@nfr.com
Cc:  
Subject: Re: misc/30631: readdir_r() SEGV on large directories
Date: Wed, 24 Oct 2001 10:38:20 -0200

 I traced the problem . The problem occurs only with -pthread library
 (not the normal
 libc). The problem is to memcpy the structure
  memcpy(entry, dp, sizeof *entry);
 in the pthread library sometimes dp doen't have the correct size
 (I don't know why or where this is  happening). I know that if we change
 this to
  memcpy(entry, dp, _GENERIC_DIRSIZ(dp));
 it begins to work (and we cut a lot of unnecessary copy in this ugly
 struct that is dirent).
 The patch to solve this is here (someone have to test and apply):
 in the /usr/src directory:
 ------------
 diff -c lib/libc/gen/readdir.c.old lib/libc/gen/readdir.c
 *** lib/libc/gen/readdir.c.old  Wed Oct 24 10:21:17 2001
 --- lib/libc/gen/readdir.c      Wed Oct 24 10:23:35 2001
 ***************
 *** 111,117 ****
                 errno = saved_errno;
 
         if (dp != NULL)
 !               memcpy(entry, dp, sizeof *entry);
 
   #ifdef _THREAD_SAFE
         _FD_UNLOCK(dirp->dd_fd, FD_READ);
 --- 111,117 ----
                 errno = saved_errno;
 
         if (dp != NULL)
 !               memcpy(entry, dp, _GENERIC_DIRSIZ(dp));
 
   #ifdef _THREAD_SAFE
         _FD_UNLOCK(dirp->dd_fd, FD_READ);
 -------------
 Thanks for fixing this:
 
         Paniago
 

From: "Carlos F. A. Paniago" <pan@panix.ecof.org.br>
To: freebsd-gnats-submit@FreeBSD.org, jfbauer@nfr.com
Cc:  
Subject: Re: misc/30631: readdir_r() SEGV on large directories
Date: Fri, 11 Jan 2002 19:08:14 -0200

 Hi, could some one fix the patch that I send to this list? Until now in
 FreeBSD 4.5 RC1 this bug still present
 If the patch is applied it pass the test of this issue.
 
 Paniago
 
 --
 Nome:  Carlos Fernando Assis Paniago
 Email: pan@panix.ecof.org.br            e       pan@cnpm.embrapa.br
 Web:   http://www.panix.ecof.org.br/    e       http://www.cnpm.embrapa.br/
 --
 
 
 
State-Changed-From-To: open->closed 
State-Changed-By: mbr 
State-Changed-When: Tue Feb 26 14:58:28 PST 2002 
State-Changed-Why:  
The fix has been comitted to both STABLE and CURRENT. 

Thanks ! 


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