From 100bccc49b23e2674a660653fa8036af3730f564 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Wed, 7 Oct 2009 06:56:52 -0600 Subject: [PATCH] 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 --- ChangeLog | 5 +++++ lib/at-func.c | 9 +++++++++ lib/openat.c | 9 +++++++++ 3 files changed, 23 insertions(+) diff --git a/ChangeLog b/ChangeLog index 96296efdd..c120c093d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2009-10-07 Eric Blake + 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... diff --git a/lib/at-func.c b/lib/at-func.c index 75c80d3c9..4e5ba2f7e 100644 --- a/lib/at-func.c +++ b/lib/at-func.c @@ -89,6 +89,15 @@ AT_FUNC_NAME (int fd, char const *file AT_FUNC_POST_FILE_PARAM_DECLS) 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) { diff --git a/lib/openat.c b/lib/openat.c index 079039fee..aae77824a 100644 --- a/lib/openat.c +++ b/lib/openat.c @@ -202,6 +202,15 @@ openat_permissive (int fd, char const *file, int flags, mode_t mode, 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; -- 2.11.0