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>
index | next in thread | raw e-mail
>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:
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199705061504.IAA15277>
