Subject: bug#79433: 9.7: cp(1): lchownat(2/3) fallback bogus?

From: Paul Eggert <[email-masked]>
Date: Sat, 13 Sep 2025 10:17:30 -0700

On 2025-09-13 07:56, Steffen Nurpmeso wrote:

>   |What does "strace cp -a xb xc" say? I see this:
> 
>    geteuid()                               = 1000
>    openat(AT_FDCWD, "c", O_RDONLY|O_PATH|O_DIRECTORY) = -1 ENOENT (No such file or directory)
>    newfstatat(AT_FDCWD, "b", {st_mode=S_IFLNK|0777, st_size=1, ...}, AT_SYMLINK_NOFOLLOW) = 0
>    newfstatat(AT_FDCWD, "c", 0x7ffdf869dea0, AT_SYMLINK_NOFOLLOW) = -1 ENOENT (No such file or directory)
>    readlink("b", "a", 2)                   = 1
>    symlinkat("a", AT_FDCWD, "c")           = 0
>    newfstatat(AT_FDCWD, "c", {st_mode=S_IFLNK|0777, st_size=1, ...}, AT_SYMLINK_NOFOLLOW) = 0
>    lchown("c", 1000, 1000)                 = 0
>    fchmodat2(AT_FDCWD, "c", 0777, AT_SYMLINK_NOFOLLOW) = -1 ENOSYS (Function not implemented)
> ^^

So far the bug report has been about lchownat. But now you're saying 
that cp fails because fchmodat2 fails. So it sounds like we have been 
barking up the wrong tree by worrying about the chown-related syscalls, 
and that we should instead worry about chmod-related syscalls.

> I do not know how
> 
>    $ grep -r fchmodat2 /usr/include/
>    /usr/include/bits/syscall.h:#ifdef __NR_fchmodat2
>    /usr/include/bits/syscall.h:# define SYS_fchmodat2 __NR_fchmodat2
> 
> gets into there, the kernel definitely does not have that as via
> grep.  Generated at glibc build time via
> 
>      # install kernel headers
>      make -C /usr/src/linux mrproper
>      make -C /usr/src/linux INSTALL_HDR_PATH=$PKG/usr headers_install

Recent glibc fchmodat uses fchmodat2 if available. It assumes fchmodat2 
is available if __ASSUME_FCHMODAT2 is nonzero, and __ASSUME_FCHMODAT2 is 
nonzero if you build glibc with headers from Linux kernel 6.6 or later.

It sounds like your glibc was built with __ASSUME_FCHMODAT2 = 1, but is 
running atop an older kernel lacking fchmodat2. If so, that would 
explain the abovementioned symptoms, and it would be a bug in how your 
glibc was built, not a coreutils bug.