From owner-freebsd-bugs Mon Sep 17 8:40:28 2001 Delivered-To: freebsd-bugs@hub.freebsd.org Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id 7777437B40C for ; Mon, 17 Sep 2001 08:40:06 -0700 (PDT) Received: (from gnats@localhost) by freefall.freebsd.org (8.11.4/8.11.4) id f8HFe6G70780; Mon, 17 Sep 2001 08:40:06 -0700 (PDT) (envelope-from gnats) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id 433D037B405 for ; 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 To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-1.0 Subject: misc/30631: readdir_r() SEGV on large directories Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org >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 #include 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