This is the mail archive of the cygwin-patches mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: fcntl bug


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

According to Christopher Faylor on 8/30/2009 6:55 PM:
> On Sun, Aug 30, 2009 at 06:32:59PM -0600, Eric Blake wrote:
>> According to Eric Blake on 8/24/2009 9:15 AM:
>>> While we're at it, fcntl and dup2 both have another minor bug.  POSIX
>>> states that fcntl(0,F_DUPFD,10000000) should fail with EINVAL (not
>>> EBADF) and the similar dup2(0,10000000) should fail with EBADF (not
>>> EMFILE).
>> Ping.  Cygwin is currently failing a test in coreutils' 7.5 testsuite
>> because of this.
> 
> I have no intention of going to the effort of fixing these trivial
> problems.
> 
> If it is important to you then please provide a patch.

2009-09-03  Eric Blake  <ebb9@byu.net>

	* dtable.h (OPEN_MAX_MAX): New macro.
	* resource.cc (getrlimit) [RLIMIT_NOFILE]: Use it.
	* dtable.cc (dtable::extend): Likewise.
	* fcntl.cc (fcntl64): Obey POSIX rules.
	* syscalls.cc (dup2): Likewise.

- --
Don't work too hard, make some time for fun as well!

Eric Blake             ebb9@byu.net
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkqgE9IACgkQ84KuGfSFAYC8WgCgxBHm0hPfTe88K6m+pgr3qJVI
hsIAoMIiyeAGI10eC+b7A7eNaPjxUi+G
=Y9VB
-----END PGP SIGNATURE-----
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);
 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]