GNU bug report logs -
#79433
9.7: cp(1): lchownat(2/3) fallback bogus?
Previous Next
Full log
Message #20 received at 79433 <at> debbugs.gnu.org (full text, mbox):
On 2025-09-11 04:49, Steffen Nurpmeso wrote:
> if (lchownat (dst_dirfd, relname, p->st.st_uid, p->st.st_gid)
> != 0)
> ...
> error (0, errno, _("failed to preserve ownership for %s"),
> quoteaf (dst_name));
>
> Here there is no lchownat(3/2),
No kernel or C library has lchownat; that's a convenience function
defined in coreutils/lib/openat.h (taken from Gnulib), equivalent to
fchownat (..., AT_SYMLINK_NOFOLLOW).
What does "strace cp -a xb xc" say? I see this:
...
geteuid32() = 1000
openat(AT_FDCWD, "xb", O_RDONLY|O_LARGEFILE|O_PATH|O_DIRECTORY) = -1
ENOENT (No such file or directory)
statx(AT_FDCWD, "xa",
AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT,
STATX_BASIC_STATS, {stx_mask=STATX_BASIC_STATS|STATX_MNT_ID,
stx_attributes=0, stx_mode=S_IFREG|0664, stx_size=4, ...}) = 0
lgetxattr("xa", "security.selinux",
"unconfined_u:object_r:user_tmp_t"..., 255) = 36
futex(0xf7f7ccc4, FUTEX_WAKE_PRIVATE, 2147483647) = 0
openat(AT_FDCWD, "/proc/thread-self/attr/fscreate",
O_RDWR|O_LARGEFILE|O_CLOEXEC) = 3
write(3, "unconfined_u:object_r:user_tmp_t"..., 36) = 36
close(3) = 0
openat(AT_FDCWD, "xa", O_RDONLY|O_LARGEFILE|O_NOFOLLOW) = 3
statx(3, "", AT_STATX_SYNC_AS_STAT|AT_NO_AUTOMOUNT|AT_EMPTY_PATH,
STATX_BASIC_STATS, {stx_mask=STATX_BASIC_STATS|STATX_MNT_ID,
stx_attributes=0, stx_mode=S_IFREG|0664, stx_size=4, ...}) = 0
openat(AT_FDCWD, "xb", O_WRONLY|O_CREAT|O_EXCL|O_LARGEFILE, 0600) = 4
ioctl(4, BTRFS_IOC_CLONE or FICLONE, 3) = -1 EOPNOTSUPP (Operation
not supported)
statx(4, "", AT_STATX_SYNC_AS_STAT|AT_NO_AUTOMOUNT|AT_EMPTY_PATH,
STATX_BASIC_STATS, {stx_mask=STATX_BASIC_STATS|STATX_MNT_ID,
stx_attributes=0, stx_mode=S_IFREG|0600, stx_size=0, ...}) = 0
fadvise64_64(3, 0, 0, POSIX_FADV_SEQUENTIAL) = 0
uname({sysname="Linux", nodename="penguin.cs.ucla.edu", ...}) = 0
copy_file_range(3, NULL, 4, NULL, 1073741824, 0) = 4
copy_file_range(3, NULL, 4, NULL, 1073741824, 0) = 0
utimensat(4, NULL, [{tv_sec=1757689789, tv_nsec=946283700} /*
2025-09-12T08:09:49.946283700-0700 */, {tv_sec=1757689789,
tv_nsec=946283700} /* 2025-09-12T08:09:49.946283700-0700 */], 0) = 0
flistxattr(3, NULL, 0) = 17
flistxattr(3, "security.selinux\0", 17) = 17
fchmod(4, 0100664) = 0
flistxattr(3, NULL, 0) = 17
flistxattr(3, "security.selinux\0", 17) = 17
openat(AT_FDCWD, "/etc/xattr.conf", O_RDONLY|O_LARGEFILE) = 5
statx(5, "", AT_STATX_SYNC_AS_STAT|AT_NO_AUTOMOUNT|AT_EMPTY_PATH,
STATX_BASIC_STATS, {stx_mask=STATX_BASIC_STATS|STATX_MNT_ID,
stx_attributes=0, stx_mode=S_IFREG|0644, stx_size=817, ...}) = 0
read(5, "# /etc/xattr.conf\n#\n# Format:\n# "..., 4096) = 817
read(5, "", 4096) = 0
close(5) = 0
openat(AT_FDCWD, "/usr/lib/gconv/gconv-modules.cache",
O_RDONLY|O_CLOEXEC) = 5
statx(5, "", AT_STATX_SYNC_AS_STAT|AT_NO_AUTOMOUNT|AT_EMPTY_PATH,
STATX_BASIC_STATS, {stx_mask=STATX_BASIC_STATS|STATX_MNT_ID,
stx_attributes=0, stx_mode=S_IFREG|0644, stx_size=27010, ...}) = 0
mmap2(NULL, 27010, PROT_READ, MAP_SHARED, 5, 0) = 0xf7f99000
close(5) = 0
futex(0xf7f2eee8, FUTEX_WAKE_PRIVATE, 2147483647) = 0
close(4) = 0
close(3) = 0
...
What happens if you use fchownat directly? Something like the following:
#include <errno.h>
#include <fcntl.h>
#include <grp.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int
main (void)
{
char const *user = getenv ("LOGNAME");
struct passwd const *pwd = getpwnam (user);
struct group const *grp = getgrnam (user);
int x = fchownat (AT_FDCWD, "xb",
pwd->pw_uid, grp->gr_gid,
AT_SYMLINK_NOFOLLOW);
if (x < 0)
perror ("fchownat");
int y = lchown ("xb", pwd->pw_uid, grp->gr_gid);
if (y < 0)
perror ("lchown");
}
I see this:
...
fchownat(AT_FDCWD, "xb", 1000, 1000, AT_SYMLINK_NOFOLLOW) = 0
lchown("xb", 1000, 1000) = 0
...
This bug report was last modified 1 day ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.