Date: Tue, 6 May 1997 08:04:50 -0700 (PDT) From: mflatt@cs.rice.edu To: freebsd-gnats-submit@FreeBSD.ORG Subject: bin/3516: getcwd() fails to close a DIR* when the path buffer is too small Message-ID: <199705061504.IAA15277@hub.freebsd.org> Resent-Message-ID: <199705061510.IAA15604@hub.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 3516 >Category: bin >Synopsis: getcwd() fails to close a DIR* when the path buffer is too small >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Tue May 6 08:10:01 PDT 1997 >Last-Modified: >Originator: Matthew Flatt >Organization: Rice PLT >Release: 2.1.7 >Environment: FreeBSD new-world.cs.rice.edu 2.1.7-RELEASE FreeBSD 2.1.7-RELEASE #0: Wed Feb 12 00:01:51 CST 1997 root@new-world.cs.rice.edu:/usr/src/sys/compile/NEWORLD i386 >Description: getcwd() takes a buffer and the buffer's size as the first two arguments. If this buffer is large enough that getcwd() opens a directory using opendir(), but too small to hold the directory's name, it returns ERANGE (correct) but does not close the directory with closedir() (incorrect) resulting in a file descriptor leak. >How-To-Repeat: #include <unistd.h> #include <errno.h> #include <stdio.h> #define SIZE 20 int main(int argc, char **argv) { char small[SIZE]; int count = 0; /* Should loop forever */ while (1) { count++; if (!getcwd(small, SIZE)) { if (errno != ERANGE) { printf("bad getcwd error (%d) at attempt %d\n", errno, count); return -1; } } } return 0; } >Fix: *** /usr/src/lib/libc/gen/getcwd.c Mon May 5 22:08:40 1997 --- /home/mflatt/tmp/getcwd.c Tue May 6 10:00:20 1997 *************** *** 55,61 **** size_t size; { register struct dirent *dp; ! register DIR *dir; register dev_t dev; register ino_t ino; register int first; --- 55,61 ---- size_t size; { register struct dirent *dp; ! register DIR *dir = NULL; register dev_t dev; register ino_t ino; register int first; *************** *** 213,218 **** --- 213,219 ---- bpt -= dp->d_namlen; bcopy(dp->d_name, bpt, dp->d_namlen); (void)closedir(dir); + dir = NULL; /* Truncate any file name. */ *bup = '\0'; *************** *** 230,235 **** --- 231,237 ---- err: if (ptsize) free(pt); + if (dir) (void)closedir(dir); free(up); return (NULL); } >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199705061504.IAA15277>