changeset 12132:8e0dac113023

openat: avoid using wrong fd Detected by a Solaris failure on: int fd = dup (0); close (fd); mkdirat (fd, "dir", 0700); which created "./dir" instead of failing with EBADF. * lib/openat.c (openat_permissive): Reject user's fd if saving the working directory chooses same fd. * lib/at-func.c (AT_FUNC_NAME): Likewise. Signed-off-by: Eric Blake <ebb9@byu.net>
author Eric Blake <ebb9@byu.net>
date Wed, 07 Oct 2009 06:56:52 -0600
parents 3e62859ad66f
children 799664c0f270
files ChangeLog lib/at-func.c lib/openat.c
diffstat 3 files changed, 23 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2009-10-07  Eric Blake  <ebb9@byu.net>
 
+	openat: avoid using wrong fd
+	* lib/openat.c (openat_permissive): Reject user's fd if saving the
+	working directory chooses same fd.
+	* lib/at-func.c (AT_FUNC_NAME): Likewise.
+
 	mkdir, mkdirat: fix cygwin 1.5.x bug
 	* lib/mkdir.c (rpl_mkdir) [FUNC_MKDIR_DOT_BUG]: Work around bug.
 	* m4/mkdir-slash.m4 (gl_FUNC_MKDIR_TRAILING_SLASH): Move...
--- a/lib/at-func.c
+++ b/lib/at-func.c
@@ -89,6 +89,15 @@
 
   if (save_cwd (&saved_cwd) != 0)
     openat_save_fail (errno);
+  if (0 <= fd && fd == saved_cwd.desc)
+    {
+      /* If saving the working directory collides with the user's
+         requested fd, then the user's fd must have been closed to
+         begin with.  */
+      free_cwd (&saved_cwd);
+      errno = EBADF;
+      return -1;
+    }
 
   if (fchdir (fd) != 0)
     {
--- a/lib/openat.c
+++ b/lib/openat.c
@@ -202,6 +202,15 @@
 	openat_save_fail (errno);
       *cwd_errno = errno;
     }
+  if (0 <= fd && fd == saved_cwd.desc)
+    {
+      /* If saving the working directory collides with the user's
+         requested fd, then the user's fd must have been closed to
+         begin with.  */
+      free_cwd (&saved_cwd);
+      errno = EBADF;
+      return -1;
+    }
 
   err = fchdir (fd);
   saved_errno = errno;