diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 082c420e4..5ea8456a8 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,11 @@ +2009-09-22 Eric Blake + + * dtable.h (OPEN_MAX_MAX): New macro. + * resource.cc (getrlimit) [RLIMIT_NOFILE]: Use it. + * dtable.cc (dtable::extend): Likewise. + * fcntl.cc (fcntl64): Obey POSIX rule with too-large F_DUPFD. + * syscalls.cc (dup2): Likewise. + 2009-09-21 Corinna Vinschen * cygheap.h (cwdstuff::get_posix): Convert to const inline method just diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc index 377c138fd..ab4d1fbfd 100644 --- a/winsup/cygwin/dtable.cc +++ b/winsup/cygwin/dtable.cc @@ -80,7 +80,7 @@ dtable::extend (int howmuch) if (howmuch <= 0) return 0; - if (new_size > (100 * NOFILE_INCR)) + if (new_size > OPEN_MAX_MAX) { set_errno (EMFILE); return 0; diff --git a/winsup/cygwin/dtable.h b/winsup/cygwin/dtable.h index 9d187e819..c1344549e 100644 --- a/winsup/cygwin/dtable.h +++ b/winsup/cygwin/dtable.h @@ -1,6 +1,7 @@ /* dtable.h: fd table definition. - Copyright 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008 Red Hat, Inc. + Copyright 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Red + Hat, Inc. This file is part of Cygwin. @@ -10,6 +11,8 @@ details. */ /* Initial and increment values for cygwin's fd table */ #define NOFILE_INCR 32 +/* Maximum size we allow expanding to. */ +#define OPEN_MAX_MAX (100 * NOFILE_INCR) #include "thread.h" #include "sync.h" diff --git a/winsup/cygwin/fcntl.cc b/winsup/cygwin/fcntl.cc index bb41f05c5..78ce36569 100644 --- a/winsup/cygwin/fcntl.cc +++ b/winsup/cygwin/fcntl.cc @@ -1,6 +1,7 @@ /* fcntl.cc: fcntl syscall - Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2008 Red Hat, Inc. + Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2008, + 2009 Red Hat, Inc. This file is part of Cygwin. @@ -40,7 +41,7 @@ fcntl64 (int fd, int cmd, ...) switch (cmd) { case F_DUPFD: - if ((int) arg >= 0) + if ((int) arg >= 0 && (int) arg < OPEN_MAX_MAX) res = dup2 (fd, cygheap_fdnew (((int) arg) - 1)); else { diff --git a/winsup/cygwin/resource.cc b/winsup/cygwin/resource.cc index ee17ac880..9a2acdd1d 100644 --- a/winsup/cygwin/resource.cc +++ b/winsup/cygwin/resource.cc @@ -143,7 +143,7 @@ getrlimit (int resource, struct rlimit *rlp) rlp->rlim_cur = getdtablesize (); if (rlp->rlim_cur < OPEN_MAX) rlp->rlim_cur = OPEN_MAX; - rlp->rlim_max = 100 * NOFILE_INCR; + rlp->rlim_max = OPEN_MAX_MAX; break; case RLIMIT_CORE: rlp->rlim_cur = rlim_core; diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index a436afd52..02a49b852 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -124,6 +124,12 @@ dup (int fd) int dup2 (int oldfd, int newfd) { + if (newfd >= OPEN_MAX_MAX) + { + syscall_printf ("-1 = dup2 (%d, %d) (%d too large)", oldfd, newfd, newfd); + set_errno (EBADF); + return -1; + } return cygheap->fdtab.dup2 (oldfd, newfd); }