diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc index 3789ff5..bf6d6df 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 f685624..6949794 100644 --- a/winsup/cygwin/dtable.h +++ b/winsup/cygwin/dtable.h @@ -1,6 +1,6 @@ /* 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 +10,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 4426862..522f911 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,13 @@ fcntl64 (int fd, int cmd, ...) switch (cmd) { case F_DUPFD: - res = dup2 (fd, cygheap_fdnew (((int) arg) - 1)); + if ((int) arg >= OPEN_MAX_MAX) + { + syscall_printf ("%d too large", (int) arg); + set_errno (EINVAL); + } + else + res = dup2 (fd, cygheap_fdnew (((int) arg) - 1)); break; case F_GETLK: case F_SETLK: diff --git a/winsup/cygwin/resource.cc b/winsup/cygwin/resource.cc index ee17ac8..9a2acdd 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 fb17f1e..3798587 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 (EINVAL); + return -1; + } return cygheap->fdtab.dup2 (oldfd, newfd); }