Thanks for the followup. I looked into fixing it in Gnulib and it
appears that this would require an extra syscall (or maybe even two) per
file when copying to a CIFS filesystem, which I'd rather avoid. So I'm
leaning more towards working around the bug in coreutils. Before doing
that, it'd be helpful to know whether the bug is limited to fchownat or
(as I suspect) applies also to the other chown variants. Could you try
running the attached program on your platform, to see whether the bug
affects these other variants?
Also, could you let us know the kernel and glibc version? The bug should
be documented in gnulib/doc, I'd think. (Plus, reported to the Linux
and/or glibc maintainers....)#define _GNU_SOURCE
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
int
main (int argc, char **argv)
{
char const *file = argv[1] ? argv[1] : ".";
struct stat st;
if (lstat (file, &st) < 0)
return perror ("lstat"), 1;
int status = 0;
if (lchown (file, st.st_uid, st.st_gid) < 0)
perror ("lchown"), status = 1;
if (fchownat (AT_FDCWD, file, st.st_uid, st.st_gid, AT_SYMLINK_NOFOLLOW) < 0)
perror ("fchownat"), status = 1;
if (!S_ISLNK (st.st_mode))
{
if (chown (file, st.st_uid, st.st_gid) < 0)
perror ("chown"), status = 1;
int fd = openat (AT_FDCWD, file, O_RDONLY | O_NOFOLLOW);
if (fd < 0)
perror ("openat"), status = 1;
else if (fchown (fd, st.st_uid, st.st_gid) < 0)
perror ("fchown"), status = 1;
}
return status;
}