From: Paul Eggert Date: Sat, 20 Sep 2025 07:31:08 +0000 (-0700) Subject: fchownat: fix unlikely EOVERFLOW bug X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ad4d97cbad7589451a0ff60550f7af4233c4aeda;p=thirdparty%2Fgnulib.git 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. --- diff --git a/ChangeLog b/ChangeLog index d76f5f9038..08dd88a67a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2025-09-20 Paul Eggert + 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 diff --git a/lib/fchownat.c b/lib/fchownat.c index 453810d653..3e15fde1da 100644 --- a/lib/fchownat.c +++ b/lib/fchownat.c @@ -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: 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); }