Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 17 Sep 2001 08:34:32 -0700 (PDT)
From:      Jim Bauer <jfbauer@nfr.com>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   misc/30631: readdir_r() SEGV on large directories
Message-ID:  <200109171534.f8HFYWf70187@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         30631
>Category:       misc
>Synopsis:       readdir_r() SEGV on large directories
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Sep 17 08:40:00 PDT 2001
>Closed-Date:
>Last-Modified:
>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:
>Unformatted:

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?200109171534.f8HFYWf70187>