From a14bd223642bd4673e2561c477190875764583eb Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sat, 13 Nov 2010 15:25:14 +0100 Subject: [PATCH] openat: Work around glibc bug with fchownat() and empty file names. * m4/openat.m4 (gl_FUNC_FCHOWNAT_EMPTY_FILENAME_BUG): New macro. (gl_FUNC_FCHOWNAT): Invoke it. * lib/fchownat.c (rpl_fchownat): Handle the empty file name specially. * doc/posix-functions/fchownat.texi: Document the glibc bug. Reported by Gary V. Vaughan . --- ChangeLog | 9 +++++++++ doc/posix-functions/fchownat.texi | 3 +++ lib/fchownat.c | 7 +++++++ m4/openat.m4 | 38 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 57 insertions(+) diff --git a/ChangeLog b/ChangeLog index fa9642ace..95ce4abc1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,14 @@ 2010-11-13 Bruno Haible + openat: Work around glibc bug with fchownat() and empty file names. + * m4/openat.m4 (gl_FUNC_FCHOWNAT_EMPTY_FILENAME_BUG): New macro. + (gl_FUNC_FCHOWNAT): Invoke it. + * lib/fchownat.c (rpl_fchownat): Handle the empty file name specially. + * doc/posix-functions/fchownat.texi: Document the glibc bug. + Reported by Gary V. Vaughan . + +2010-11-13 Bruno Haible + openat: Ensure autoconf macro ordering. * m4/openat.m4 (gl_FUNC_FCHOWNAT_DEREF_BUG): Require gl_USE_SYSTEM_EXTENSIONS. diff --git a/doc/posix-functions/fchownat.texi b/doc/posix-functions/fchownat.texi index 5b953345a..24aa81675 100644 --- a/doc/posix-functions/fchownat.texi +++ b/doc/posix-functions/fchownat.texi @@ -17,6 +17,9 @@ Some platforms mistakenly dereference symlinks when using @code{AT_SYMLINK_NOFOLLOW}: Linux kernel 2.6.17. @item +This function does not fail for an empty filename on some platforms: +Linux with glibc < 2.11. +@item This function is missing on some platforms: glibc 2.3.6, MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0, OpenBSD 3.8, AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Cygwin 1.5.x, mingw, Interix 3.5, BeOS. diff --git a/lib/fchownat.c b/lib/fchownat.c index 00126acf0..55dd937a5 100644 --- a/lib/fchownat.c +++ b/lib/fchownat.c @@ -88,6 +88,13 @@ rpl_fchownat (int fd, char const *file, uid_t owner, gid_t group, int flag) if (flag == AT_SYMLINK_NOFOLLOW) return local_lchownat (fd, file, owner, group); # endif +# if FCHOWNAT_EMPTY_FILENAME_BUG + if (file[0] == '\0') + { + errno = ENOENT; + return -1; + } +# endif # if CHOWN_TRAILING_SLASH_BUG { size_t len = strlen (file); diff --git a/m4/openat.m4 b/m4/openat.m4 index 89fc8ca77..71d960141 100644 --- a/m4/openat.m4 +++ b/m4/openat.m4 @@ -99,6 +99,38 @@ main () AS_IF([test $gl_cv_func_fchownat_nofollow_works = no], [$1], [$2]) ]) +# gl_FUNC_FCHOWNAT_EMPTY_FILENAME_BUG([ACTION-IF-BUGGY[, ACTION-IF-NOT_BUGGY]]) +AC_DEFUN([gl_FUNC_FCHOWNAT_EMPTY_FILENAME_BUG], +[ + dnl Persuade glibc's to declare fchownat(). + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + + AC_CACHE_CHECK([whether fchownat works with an empty file name], + [gl_cv_func_fchownat_empty_filename_works], + [AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[#include + #include + ]], + [[int fd; + int ret; + if (mkdir ("conftestdir", 0700) < 0) + return 2; + fd = open ("conftestdir", O_RDONLY); + if (fd < 0) + return 3; + ret = fchownat (fd, "", -1, -1, 0); + close (fd); + rmdir ("conftestdir"); + return ret == 0; + ]])], + [gl_cv_func_fchownat_empty_filename_works=yes], + [gl_cv_func_fchownat_empty_filename_works=no], + [gl_cv_func_fchownat_empty_filename_works="guessing no"]) + ]) + AS_IF([test "$gl_cv_func_fchownat_empty_filename_works" != yes], [$1], [$2]) +]) + # If we have the fchownat function, and it has the bug (in glibc-2.4) # that it dereferences symlinks even with AT_SYMLINK_NOFOLLOW, then # use the replacement function. @@ -116,6 +148,12 @@ AC_DEFUN([gl_FUNC_FCHOWNAT], [Define to 1 if your platform has fchownat, but it cannot perform lchown tasks.]) ]) + gl_FUNC_FCHOWNAT_EMPTY_FILENAME_BUG( + [REPLACE_FCHOWNAT=1 + AC_DEFINE([FCHOWNAT_EMPTY_FILENAME_BUG], [1], + [Define to 1 if your platform has fchownat, but it does + not reject an empty file name.]) + ]) if test $REPLACE_CHOWN = 1; then REPLACE_FCHOWNAT=1 fi], -- 2.11.0