From: Bruno Haible Date: Mon, 22 Sep 2025 11:44:06 +0000 (+0200) Subject: fchownat: Fix test failure on OpenBSD and Cygwin 2.9 (regr. 2025-09-20). X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4e944641037342d36f31547bec6a73ca910d5bd9;p=thirdparty%2Fgnulib.git fchownat: Fix test failure on OpenBSD and Cygwin 2.9 (regr. 2025-09-20). * doc/posix-functions/fchownat.texi: Document that the dereferencing bug also affects OpenBSD and Cygwin 2.9. * m4/chown.m4 (gl_FUNC_CHOWN_CTIME): New macro, extracted from gl_FUNC_CHOWN. (gl_FUNC_CHOWN): Invoke it. * m4/fchownat.m4 (gl_FUNC_FCHOWNAT_DEREF_BUG): Guess that a platform that has the chown ctime bug also has the fchownat AT_SYMLINK_NOFOLLOW bug. * modules/fchownat (Files): Add m4/chown.m4. --- diff --git a/ChangeLog b/ChangeLog index f61718951e..e845a3c76e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2025-09-22 Bruno Haible + + fchownat: Fix test failure on OpenBSD and Cygwin 2.9 (regr. 2025-09-20). + * doc/posix-functions/fchownat.texi: Document that the dereferencing bug + also affects OpenBSD and Cygwin 2.9. + * m4/chown.m4 (gl_FUNC_CHOWN_CTIME): New macro, extracted from + gl_FUNC_CHOWN. + (gl_FUNC_CHOWN): Invoke it. + * m4/fchownat.m4 (gl_FUNC_FCHOWNAT_DEREF_BUG): Guess that a platform + that has the chown ctime bug also has the fchownat AT_SYMLINK_NOFOLLOW + bug. + * modules/fchownat (Files): Add m4/chown.m4. + 2025-09-21 Paul Eggert fchownat: fix recently introduced flag typo diff --git a/doc/posix-functions/fchownat.texi b/doc/posix-functions/fchownat.texi index 34c1d724f1..c566949911 100644 --- a/doc/posix-functions/fchownat.texi +++ b/doc/posix-functions/fchownat.texi @@ -32,7 +32,7 @@ OpenBSD 7.7. @item Some platforms mistakenly dereference symlinks when using @code{AT_SYMLINK_NOFOLLOW}: -Linux kernel 2.6.17. +Linux kernel 2.6.17, OpenBSD 7.6, Cygwin 2.9.0. @item This function does not fail for an empty filename on some platforms: Linux with glibc < 2.11. diff --git a/m4/chown.m4 b/m4/chown.m4 index f899f3b680..3b377f2989 100644 --- a/m4/chown.m4 +++ b/m4/chown.m4 @@ -1,5 +1,5 @@ # chown.m4 -# serial 39 +# serial 40 dnl Copyright (C) 1997-2001, 2003-2005, 2007, 2009-2025 Free Software dnl Foundation, Inc. dnl This file is free software; the Free Software Foundation @@ -130,39 +130,7 @@ AC_DEFUN_ONCE([gl_FUNC_CHOWN], ;; esac - dnl OpenBSD fails to update ctime if ownership does not change. - AC_CACHE_CHECK([whether chown updates ctime per POSIX], - [gl_cv_func_chown_ctime_works], - [dnl This test is tricky as it depends on timing and file timestamp - dnl resolution, and there were false positives when configuring with - dnl Linux fakeroot. Since the problem occurs only on OpenBSD and Cygwin, - dnl test only on these platforms. - AS_CASE([$host_os], - [openbsd* | cygwin*], - [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ -#include -#include -#include -#include -#include -]GL_MDA_DEFINES], - [[struct stat st1, st2; - if (close (creat ("conftest.file", 0600))) return 1; - if (stat ("conftest.file", &st1)) return 2; - sleep (1); - if (chown ("conftest.file", st1.st_uid, st1.st_gid)) return 3; - if (stat ("conftest.file", &st2)) return 4; - if (st2.st_ctime <= st1.st_ctime) return 5; - ]])], - [gl_cv_func_chown_ctime_works=yes], - [gl_cv_func_chown_ctime_works=no], - [# Obey --enable-cross-guesses. - gl_cv_func_chown_ctime_works="$gl_cross_guess_normal" - ]) - rm -f conftest.file - ], - [gl_cv_func_chown_ctime_works=yes]) - ]) + gl_FUNC_CHOWN_CTIME case "$gl_cv_func_chown_ctime_works" in *yes) ;; *) @@ -221,3 +189,47 @@ AC_DEFUN_ONCE([gl_FUNC_CHOWN_FOLLOWS_SYMLINK], ;; esac ]) + +AC_DEFUN_ONCE([gl_FUNC_CHOWN_CTIME], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CHECK_FUNCS_ONCE([chown]) + + dnl mingw lacks chown altogether. + if test $ac_cv_func_chown != no; then + dnl OpenBSD and Cygwin 2.9.0 fail to update ctime if ownership does not + dnl change. + AC_CACHE_CHECK([whether chown updates ctime per POSIX], + [gl_cv_func_chown_ctime_works], + [dnl This test is tricky as it depends on timing and file timestamp + dnl resolution, and there were false positives when configuring with + dnl Linux fakeroot. Since the problem occurs only on OpenBSD and Cygwin, + dnl test only on these platforms. + AS_CASE([$host_os], + [openbsd* | cygwin*], + [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +#include +#include +#include +]GL_MDA_DEFINES], + [[struct stat st1, st2; + if (close (creat ("conftest.file", 0600))) return 1; + if (stat ("conftest.file", &st1)) return 2; + sleep (1); + if (chown ("conftest.file", st1.st_uid, st1.st_gid)) return 3; + if (stat ("conftest.file", &st2)) return 4; + if (st2.st_ctime <= st1.st_ctime) return 5; + ]])], + [gl_cv_func_chown_ctime_works=yes], + [gl_cv_func_chown_ctime_works=no], + [# Obey --enable-cross-guesses. + gl_cv_func_chown_ctime_works="$gl_cross_guess_normal" + ]) + rm -f conftest.file + ], + [gl_cv_func_chown_ctime_works=yes]) + ]) + fi +]) diff --git a/m4/fchownat.m4 b/m4/fchownat.m4 index 300a254225..bad9b58360 100644 --- a/m4/fchownat.m4 +++ b/m4/fchownat.m4 @@ -1,5 +1,5 @@ # fchownat.m4 -# serial 8 +# serial 9 dnl Copyright (C) 2004-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -46,16 +46,18 @@ AC_DEFUN([gl_FUNC_FCHOWNAT_DEREF_BUG], AC_CACHE_CHECK([whether fchownat works with AT_SYMLINK_NOFOLLOW], [gl_cv_func_fchownat_nofollow_works], - [ - gl_dangle=conftest.dangle - # Remove any remnants of a previous test. - rm -f $gl_dangle - # Arrange for deletion of the temporary file this test creates. - ac_clean_files="$ac_clean_files $gl_dangle" - ln -s conftest.no-such $gl_dangle - AC_RUN_IFELSE( - [AC_LANG_SOURCE( - [[ + [gl_FUNC_CHOWN_CTIME + case "$gl_cv_func_chown_ctime_works" in + *yes) + gl_dangle=conftest.dangle + # Remove any remnants of a previous test. + rm -f $gl_dangle + # Arrange for deletion of the temporary file this test creates. + ac_clean_files="$ac_clean_files $gl_dangle" + ln -s conftest.no-such $gl_dangle + AC_RUN_IFELSE( + [AC_LANG_SOURCE( + [[ #include #include /* Android 4.3 declares fchownat() in instead. */ @@ -70,12 +72,27 @@ main () AT_SYMLINK_NOFOLLOW) != 0 && errno == ENOENT); } - ]])], - [gl_cv_func_fchownat_nofollow_works=yes], - [gl_cv_func_fchownat_nofollow_works=no], - [gl_cv_func_fchownat_nofollow_works="$gl_cross_guess_normal"]) - ]) - AS_IF([test "$gl_cv_func_fchownat_nofollow_works" != yes], [$1], [$2]) + ]])], + [gl_cv_func_fchownat_nofollow_works=yes], + [gl_cv_func_fchownat_nofollow_works=no], + [gl_cv_func_fchownat_nofollow_works="$gl_cross_guess_normal"]) + ;; + *) + dnl On OpenBSD and Cygwin 2.9.0, the test above would produce + dnl gl_cv_func_fchownat_nofollow_works=yes, and this would then + dnl lead to an fchownat test failure: + dnl test-lchown.h:185: assertion 'st1.st_gid == st2.st_gid' failed + dnl Since testing for this bug directly is only possible on machines + dnl where the current user is in at least two groups, we use + dnl gl_FUNC_CHOWN_CTIME as a substitute test. + gl_cv_func_fchownat_nofollow_works="guessing no" + ;; + esac + ]) + case "$gl_cv_func_fchownat_nofollow_works" in + *yes) $2 ;; + *) $1 ;; + esac ]) # gl_FUNC_FCHOWNAT_EMPTY_FILENAME_BUG([ACTION-IF-BUGGY[, ACTION-IF-NOT_BUGGY]]) diff --git a/modules/fchownat b/modules/fchownat index 31e722c89c..61e1d215a1 100644 --- a/modules/fchownat +++ b/modules/fchownat @@ -5,6 +5,7 @@ Files: lib/fchownat.c lib/at-func.c m4/fchownat.m4 +m4/chown.m4 Depends-on: unistd-h