]> git.ipfire.org Git - thirdparty/gnulib.git/commitdiff
fchownat: fix unlikely EOVERFLOW bug
authorPaul Eggert <eggert@cs.ucla.edu>
Sat, 20 Sep 2025 07:31:08 +0000 (00:31 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Sat, 20 Sep 2025 07:41:51 +0000 (00:41 -0700)
* lib/fchownat.c (rpl_fchownat) [CHOWN_TRAILING_SLASH_BUG]:
Do the right thing if fstatat fails with EOVERFLOW.
This matters only on obsolete platforms like Solaris 9,
but it’s easy to do it right.  Simplify neighboring code.

ChangeLog
lib/fchownat.c

index d76f5f90381fc12b7146739d8df4f913e621309f..08dd88a67a3bb6a13472f3a3f385ed0bbc178e38 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2025-09-20  Paul Eggert  <eggert@cs.ucla.edu>
 
+       fchownat: fix unlikely EOVERFLOW bug
+       * lib/fchownat.c (rpl_fchownat) [CHOWN_TRAILING_SLASH_BUG]:
+       Do the right thing if fstatat fails with EOVERFLOW.
+       This matters only on obsolete platforms like Solaris 9,
+       but it’s easy to do it right.  Simplify neighboring code.
+
        fchownat: fix missing HAVE_FCHOWNAT
        * m4/fchownat.m4 (gl_FUNC_FCHOWNAT): Use AC_CHECK_FUNCS instead of
        AC_CHECK_FUNC, so that we define HAVE_FCHOWNAT if fchownat
index 453810d653d72aa9735948ce4303aa5ede068053..3e15fde1daf18f48cd5ff09c2334be6510807e82 100644 (file)
@@ -1,4 +1,6 @@
-/* This function serves as replacement for a missing fchownat function,
+/* A more POSIX-compliant fchownat
+
+   This serves as replacement for a missing fchownat function,
    as well as a workaround for the fchownat bug in glibc-2.4:
     <https://lists.ubuntu.com/archives/ubuntu-users/2006-September/093218.html>
    when the buggy fchownat-with-AT_SYMLINK_NOFOLLOW operates on a symlink, it
@@ -98,17 +100,14 @@ rpl_fchownat (int fd, char const *file, uid_t owner, gid_t group, int flag)
     }
 # endif
 # if CHOWN_TRAILING_SLASH_BUG
-  {
-    size_t len = strlen (file);
-    struct stat st;
-    if (len && file[len - 1] == '/')
-      {
-        if (fstatat (fd, file, &st, 0))
-          return -1;
-        if (flag == AT_SYMLINK_NOFOLLOW)
-          return fchownat (fd, file, owner, group, 0);
-      }
-  }
+  if (file[0] && file[strlen (file) - 1] == '/')
+    {
+      struct stat st;
+      int r = fstatat (fd, file, &st, 0);
+      if (r < 0 && errno != EOVERFLOW)
+        return r;
+      flag &= ~AT_SYMLINK_NOFOLLOW;
+    }
 # endif
   return fchownat (fd, file, owner, group, flag);
 }