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;
}

Reply via email to