On 2023-09-01 08:09, Bruno Haible wrote:
It applies to all 4 variants, as can be seen from applying it to a directory:

$ ./a.out /media/nas/bruno/dir1
lchown: Permission denied
fchownat: Permission denied
chown: Permission denied
fchown: Permission denied

Thanks, for coreutils it'd be helpful to now whether there's a similar problem with chmod-related syscalls. If you compile and run the attached program on a file that you don't own (e.g., './a.out /'), does it incorrectly issue "Permission denied" instead of "Operation not permitted" diagnostics?
#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;
  mode_t mode = st.st_mode & 07777;
  int status = 0;
  if (lchmod (file, mode) < 0)
    perror ("lchmod"), status = 1;
  if (fchmodat (AT_FDCWD, file, mode, AT_SYMLINK_NOFOLLOW) < 0)
    perror ("fchmodat"), status = 1;
  if (!S_ISLNK (st.st_mode))
    {
      if (chmod (file, mode) < 0)
	perror ("chmod"), status = 1;
      int fd = openat (AT_FDCWD, file, O_RDONLY | O_NOFOLLOW);
      if (fd < 0)
	perror ("openat"), status = 1;
      else if (fchmod (fd, mode) < 0)
	perror ("fchmod"), status = 1;
    }
  return status;
}

Reply via email to