--- Begin Message ---
Package: release.debian.org
Severity: normal
X-Debbugs-Cc: coreutils@packages.debian.org, Michael Stone <mstone@debian.org>, carnil@debian.org
Control: affects -1 + src:coreutils
User: release.debian.org@packages.debian.org
Usertags: unblock
Hi
Michael, I hope I overstep here not my lines, and I ssuming you were
going to do this later (but I'm not 100% sure if it was clear at this
point that we need a unblock request for this change as coreutils is a
keypackage). Please let me know if I jusged this wrongly and I should
have hold back instead filling the unblock request, I hope it was
helpful that I wanted to help getting the change into trixie.
[ Reason ]
coreutils in trixie, without the backported upstream change from
coreutils/9.7-3 has spurious permission denied errors messages when
copying from a file with NFS ACLs to a filesystem which supports
different ACLs. (when using --preserve=mode flag).
[ Impact ]
It can confuse scripts which use the flag to cp, and check the return
value as this while the file is copies sucessfully gives another
exist status as in stable. Upstream has addressed this but (to time of
writing not yet in a released version).
[ Tests ]
Manual test of a setup copying a file from a NFS share to another
filesystem supporting ACLs but not on NFS, and verifying the exist
status of the call (including strace analysis).
[ Risks ]
It is a change from upstream. As I'm not involved upstream it is bit
hard of judging on potential risk, but the change looks safe to me and
ocrrects the behaviour (where the regressions seems worse to me to
have in trixe).
[ Checklist ]
[x] all changes are documented in the d/changelog
[x] I reviewed all changes and I approve them, but see above comment
in the Risks session.
[x] attach debdiff against the package in testing
[ Other info ]
See the introductory comment. I hope Michael can give a comment on his
own as well for the need of this change to enter trixie.
unblock coreutils/9.7-3
Regards,
Salvatore
diff -Nru coreutils-9.7/debian/changelog coreutils-9.7/debian/changelog
--- coreutils-9.7/debian/changelog 2025-04-20 19:39:09.000000000 +0200
+++ coreutils-9.7/debian/changelog 2025-06-04 17:14:05.000000000 +0200
@@ -1,3 +1,14 @@
+coreutils (9.7-3) unstable; urgency=high
+
+ * Correct spurious permission denied errors messages when copying from a file
+ with NFS ACLs to a filesystem which supports different ACLs.
+ (Backport of upstream fix.) (Closes: #1107169)
+ * Additional lintian overrides (for "mono", which is not defined for
+ terminals but is for other output formats) to address remaining lintian
+ warnings.
+
+ -- Michael Stone <mstone@debian.org> Wed, 04 Jun 2025 11:14:05 -0400
+
coreutils (9.7-2) unstable; urgency=low
* Build without y2038 support on hurd-i386 (Closes: #1078000)
diff -Nru coreutils-9.7/debian/coreutils.lintian-overrides coreutils-9.7/debian/coreutils.lintian-overrides
--- coreutils-9.7/debian/coreutils.lintian-overrides 2025-04-20 19:25:53.000000000 +0200
+++ coreutils-9.7/debian/coreutils.lintian-overrides 2025-06-04 17:14:05.000000000 +0200
@@ -1 +1,3 @@
coreutils: custom-library-search-path RUNPATH /usr/lib/*
+coreutils: groff-message *warning: macro 'mono' not defined*
+coreutils: groff-message *warning: macro '/mono' not defined*
diff -Nru coreutils-9.7/debian/patches/gnulib-nfs-acl.patch coreutils-9.7/debian/patches/gnulib-nfs-acl.patch
--- coreutils-9.7/debian/patches/gnulib-nfs-acl.patch 1970-01-01 01:00:00.000000000 +0100
+++ coreutils-9.7/debian/patches/gnulib-nfs-acl.patch 2025-06-04 17:14:05.000000000 +0200
@@ -0,0 +1,449 @@
+Author: Paul Eggert <eggert@cs.ucla.edu>
+Description: addresses spurious cp permission errors
+===================================================================
+diff --git a/lib/acl.h b/lib/acl.h
+index 90fd24e152..e3c134fb41 100644
+--- a/lib/acl.h
++++ b/lib/acl.h
+@@ -79,6 +79,8 @@ struct aclinfo
+ bool acl_errno_valid (int) _GL_ATTRIBUTE_CONST;
+ int file_has_acl (char const *, struct stat const *);
+ int file_has_aclinfo (char const *restrict, struct aclinfo *restrict, int);
++int fdfile_has_aclinfo (int, char const *restrict,
++ struct aclinfo *restrict, int);
+
+ #if HAVE_LINUX_XATTR_H && HAVE_LISTXATTR
+ bool aclinfo_has_xattr (struct aclinfo const *, char const *)
+diff --git a/lib/copy-acl.c b/lib/copy-acl.c
+index c36f64e51d..2fce6c7d46 100644
+--- a/lib/copy-acl.c
++++ b/lib/copy-acl.c
+@@ -33,6 +33,7 @@
+ a valid file descriptor, use file descriptor operations, else use
+ filename based operations on SRC_NAME. Likewise for DEST_DESC and
+ DST_NAME.
++ MODE should be the source file's st_mode.
+ If access control lists are not available, fchmod the target file to
+ MODE. Also sets the non-permission bits of the destination file
+ (S_ISUID, S_ISGID, S_ISVTX) to those from MODE if any are set.
+diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c
+index 66b920c1ab..a356ee0d0b 100644
+--- a/lib/file-has-acl.c
++++ b/lib/file-has-acl.c
+@@ -85,6 +85,13 @@ smack_new_label_from_path (MAYBE_UNUSED const char *path,
+ {
+ return -1;
+ }
++static ssize_t
++smack_new_label_from_file (MAYBE_UNUSED int fd,
++ MAYBE_UNUSED const char *xattr,
++ MAYBE_UNUSED char **label)
++{
++ return -1;
++}
+ # endif
+ static bool
+ is_smack_enabled (void)
+@@ -115,14 +122,16 @@ aclinfo_may_indicate_xattr (struct aclinfo const *ai)
+
+ static bool
+ has_xattr (char const *xattr, struct aclinfo const *ai,
+- MAYBE_UNUSED char const *restrict name, MAYBE_UNUSED int flags)
++ int fd, char const *restrict name, int flags)
+ {
+ if (ai && aclinfo_has_xattr (ai, xattr))
+ return true;
+ else if (!ai || aclinfo_may_indicate_xattr (ai))
+ {
+- int ret = ((flags & ACL_SYMLINK_FOLLOW ? getxattr : lgetxattr)
+- (name, xattr, NULL, 0));
++ int ret = (fd < 0
++ ? ((flags & ACL_SYMLINK_FOLLOW ? getxattr : lgetxattr)
++ (name, xattr, NULL, 0))
++ : fgetxattr (fd, xattr, NULL, 0));
+ if (0 <= ret || (errno == ERANGE || errno == E2BIG))
+ return true;
+ }
+@@ -145,11 +154,12 @@ aclinfo_has_xattr (struct aclinfo const *ai, char const *xattr)
+ return false;
+ }
+
+-/* Get attributes of the file NAME into AI, if USE_ACL.
++/* Get attributes of the file FD aka NAME into AI, if USE_ACL.
++ Ignore FD if it is negative.
+ If FLAGS & ACL_GET_SCONTEXT, also get security context.
+ If FLAGS & ACL_SYMLINK_FOLLOW, follow symbolic links. */
+ static void
+-get_aclinfo (char const *name, struct aclinfo *ai, int flags)
++get_aclinfo (int fd, char const *name, struct aclinfo *ai, int flags)
+ {
+ int scontext_err = ENOTSUP;
+ ai->buf = ai->u.__gl_acl_ch;
+@@ -163,7 +173,9 @@ get_aclinfo (char const *name, struct aclinfo *ai, int flags)
+ = (flags & ACL_SYMLINK_FOLLOW ? listxattr : llistxattr);
+ while (true)
+ {
+- ai->size = lsxattr (name, ai->buf, acl_alloc);
++ ai->size = (fd < 0
++ ? lsxattr (name, ai->buf, acl_alloc)
++ : flistxattr (fd, ai->buf, acl_alloc));
+ if (0 < ai->size)
+ break;
+ ai->u.err = ai->size < 0 ? errno : 0;
+@@ -171,7 +183,9 @@ get_aclinfo (char const *name, struct aclinfo *ai, int flags)
+ break;
+
+ /* The buffer was too small. Find how large it should have been. */
+- ssize_t size = lsxattr (name, NULL, 0);
++ ssize_t size = (fd < 0
++ ? lsxattr (name, NULL, 0)
++ : flistxattr (fd, NULL, 0));
+ if (size <= 0)
+ {
+ ai->size = size;
+@@ -214,9 +228,13 @@ get_aclinfo (char const *name, struct aclinfo *ai, int flags)
+ {
+ if (ai->size < 0 || aclinfo_has_xattr (ai, XATTR_NAME_SMACK))
+ {
+- ssize_t r = smack_new_label_from_path (name, "security.SMACK64",
+- flags & ACL_SYMLINK_FOLLOW,
+- &ai->scontext);
++ static char const SMACK64[] = "security.SMACK64";
++ ssize_t r =
++ (fd < 0
++ ? smack_new_label_from_path (name, SMACK64,
++ flags & ACL_SYMLINK_FOLLOW,
++ &ai->scontext)
++ : smack_new_label_from_file (fd, SMACK64, &ai->scontext));
+ scontext_err = r < 0 ? errno : 0;
+ }
+ }
+@@ -226,8 +244,10 @@ get_aclinfo (char const *name, struct aclinfo *ai, int flags)
+ if (ai->size < 0 || aclinfo_has_xattr (ai, XATTR_NAME_SELINUX))
+ {
+ ssize_t r =
+- ((flags & ACL_SYMLINK_FOLLOW ? getfilecon : lgetfilecon)
+- (name, &ai->scontext));
++ (fd < 0
++ ? ((flags & ACL_SYMLINK_FOLLOW ? getfilecon : lgetfilecon)
++ (name, &ai->scontext))
++ : fgetfilecon (fd, &ai->scontext));
+ scontext_err = r < 0 ? errno : 0;
+ # ifndef SE_SELINUX_INLINE
+ /* Gnulib's selinux-h module is not in use, so getfilecon and
+@@ -362,11 +382,13 @@ acl_nfs4_nontrivial (uint32_t *xattr, ssize_t nbytes)
+ }
+ #endif
+
+-#if (!USE_LINUX_XATTR && USE_ACL && HAVE_ACL_GET_FD \
+- && !HAVE_ACL_EXTENDED_FILE && !HAVE_ACL_TYPE_EXTENDED \
+- && !HAVE_ACL_GET_LINK_NP)
+-# include <fcntl.h>
+-# ifdef O_PATH
++#if (!USE_LINUX_XATTR && USE_ACL && !HAVE_ACL_EXTENDED_FILE \
++ && !HAVE_ACL_TYPE_EXTENDED)
++
++# if HAVE_ACL_GET_FD && !HAVE_ACL_GET_LINK_NP
++# include <fcntl.h>
++# ifdef O_PATH
++# define acl_get_fd_np(fd, type) acl_get_fd (fd)
+
+ /* Like acl_get_file, but do not follow symbolic links. */
+ static acl_t
+@@ -381,8 +403,24 @@ acl_get_link_np (char const *name, acl_type_t type)
+ errno = err;
+ return r;
+ }
+-# define HAVE_ACL_GET_LINK_NP 1
++# define HAVE_ACL_GET_LINK_NP 1
++# endif
+ # endif
++
++static acl_t
++acl_get_fdfile (int fd, char const *name, acl_type_t type, int flags)
++{
++ acl_t (*get) (char const *, acl_type_t) = acl_get_file;
++# if HAVE_ACL_GET_LINK_NP /* FreeBSD, NetBSD >= 10, Cygwin >= 2.5 */
++ if (0 <= fd)
++ return acl_get_fd_np (fd, type);
++ if (! (flags & ACL_SYMLINK_FOLLOW))
++ get = acl_get_link_np;
++# else
++ /* Ignore FD and FLAGS, unfortunately. */
++# endif
++ return get (name, type);
++}
+ #endif
+
+ /* Return 1 if NAME has a nontrivial access control list,
+@@ -398,14 +436,35 @@ acl_get_link_np (char const *name, acl_type_t type)
+ If the d_type value is not known, use DT_UNKNOWN though this may be less
+ efficient. */
+ int
+-file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
++file_has_aclinfo (char const *restrict name,
+ struct aclinfo *restrict ai, int flags)
++{
++ return fdfile_has_aclinfo (-1, name, ai, flags);
++}
++
++/* Return 1 if FD aka NAME has a nontrivial access control list,
++ 0 if ACLs are not supported, or if NAME has no or only a base ACL,
++ and -1 (setting errno) on error. Note callers can determine
++ if ACLs are not supported as errno is set in that case also.
++ Ignore FD if it is negative.
++ Set *AI to ACL info regardless of return value.
++ FLAGS should be a <dirent.h> d_type value, optionally ORed with
++ - _GL_DT_NOTDIR if it is known that NAME is not a directory,
++ - ACL_GET_SCONTEXT to retrieve security context and return 1 if present,
++ - ACL_SYMLINK_FOLLOW to follow the link if NAME is a symbolic link;
++ otherwise do not follow them if possible.
++ If the d_type value is not known, use DT_UNKNOWN though this may be less
++ efficient. */
++int
++fdfile_has_aclinfo (MAYBE_UNUSED int fd,
++ MAYBE_UNUSED char const *restrict name,
++ struct aclinfo *restrict ai, int flags)
+ {
+ MAYBE_UNUSED unsigned char d_type = flags & UCHAR_MAX;
+
+ #if USE_LINUX_XATTR
+ int initial_errno = errno;
+- get_aclinfo (name, ai, flags);
++ get_aclinfo (fd, name, ai, flags);
+
+ if (!aclinfo_may_indicate_xattr (ai) && ai->size <= 0)
+ {
+@@ -418,11 +477,11 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
+ In earlier Fedora the two types of ACLs were mutually exclusive.
+ Attempt to work correctly on both kinds of systems. */
+
+- if (!has_xattr (XATTR_NAME_NFSV4_ACL, ai, name, flags))
++ if (!has_xattr (XATTR_NAME_NFSV4_ACL, ai, fd, name, flags))
+ return
+- (has_xattr (XATTR_NAME_POSIX_ACL_ACCESS, ai, name, flags)
++ (has_xattr (XATTR_NAME_POSIX_ACL_ACCESS, ai, fd, name, flags)
+ || ((d_type == DT_DIR || d_type == DT_UNKNOWN)
+- && has_xattr (XATTR_NAME_POSIX_ACL_DEFAULT, ai, name, flags)));
++ && has_xattr (XATTR_NAME_POSIX_ACL_DEFAULT, ai, fd, name, flags)));
+
+ /* A buffer large enough to hold any trivial NFSv4 ACL.
+ The max length of a trivial NFSv4 ACL is 6 words for owner,
+@@ -432,8 +491,10 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
+ everyone is another word to hold "EVERYONE@". */
+ uint32_t buf[2 * (6 + 6 + 7)];
+
+- int ret = ((flags & ACL_SYMLINK_FOLLOW ? getxattr : lgetxattr)
+- (name, XATTR_NAME_NFSV4_ACL, buf, sizeof buf));
++ int ret = (fd < 0
++ ? ((flags & ACL_SYMLINK_FOLLOW ? getxattr : lgetxattr)
++ (name, XATTR_NAME_NFSV4_ACL, buf, sizeof buf))
++ : fgetxattr (fd, XATTR_NAME_NFSV4_ACL, buf, sizeof buf));
+ if (ret < 0)
+ switch (errno)
+ {
+@@ -467,20 +528,23 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
+ /* On Linux, acl_extended_file is an optimized function: It only
+ makes two calls to getxattr(), one for ACL_TYPE_ACCESS, one for
+ ACL_TYPE_DEFAULT. */
+- ret = ((flags & ACL_SYMLINK_FOLLOW
+- ? acl_extended_file
+- : acl_extended_file_nofollow)
+- (name));
++ ret = (fd < 0
++ ? ((flags & ACL_SYMLINK_FOLLOW
++ ? acl_extended_file
++ : acl_extended_file_nofollow)
++ (name))
++ : acl_extended_fd (fd));
+ # elif HAVE_ACL_TYPE_EXTENDED /* Mac OS X */
+ /* On Mac OS X, acl_get_file (name, ACL_TYPE_ACCESS)
+ and acl_get_file (name, ACL_TYPE_DEFAULT)
+ always return NULL / EINVAL. There is no point in making
+ these two useless calls. The real ACL is retrieved through
+- acl_get_file (name, ACL_TYPE_EXTENDED). */
+- acl_t acl = ((flags & ACL_SYMLINK_FOLLOW
+- ? acl_get_file
+- : acl_get_link_np)
+- (name, ACL_TYPE_EXTENDED));
++ ACL_TYPE_EXTENDED. */
++ acl_t acl =
++ (fd < 0
++ ? ((flags & ACL_SYMLINK_FOLLOW ? acl_get_file : acl_get_link_np)
++ (name, ACL_TYPE_EXTENDED))
++ : acl_get_fd_np (fd, ACL_TYPE_EXTENDED));
+ if (acl)
+ {
+ ret = acl_extended_nontrivial (acl);
+@@ -489,13 +553,8 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
+ else
+ ret = -1;
+ # else /* FreeBSD, NetBSD >= 10, IRIX, Tru64, Cygwin >= 2.5 */
+- acl_t (*acl_get_file_or_link) (char const *, acl_type_t) = acl_get_file;
+-# if HAVE_ACL_GET_LINK_NP /* FreeBSD, NetBSD >= 10, Cygwin >= 2.5 */
+- if (! (flags & ACL_SYMLINK_FOLLOW))
+- acl_get_file_or_link = acl_get_link_np;
+-# endif
+
+- acl_t acl = acl_get_file_or_link (name, ACL_TYPE_ACCESS);
++ acl_t acl = acl_get_fdfile (fd, name, ACL_TYPE_ACCESS, flags);
+ if (acl)
+ {
+ ret = acl_access_nontrivial (acl);
+@@ -517,7 +576,7 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
+ && (d_type == DT_DIR
+ || (d_type == DT_UNKNOWN && !(flags & _GL_DT_NOTDIR))))
+ {
+- acl = acl_get_file_or_link (name, ACL_TYPE_DEFAULT);
++ acl = acl_get_fdfile (fd, name, ACL_TYPE_DEFAULT, flags);
+ if (acl)
+ {
+ # ifdef __CYGWIN__ /* Cygwin >= 2.5 */
+@@ -562,7 +621,10 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
+
+ /* Solaris 10 (newer version), which has additional API declared in
+ <sys/acl.h> (acl_t) and implemented in libsec (acl_set, acl_trivial,
+- acl_fromtext, ...). */
++ acl_fromtext, ...).
++
++ Ignore FD, unfortunately. That is better than mishandling
++ ZFS-style ACLs, as the general case code does. */
+ return acl_trivial (name);
+
+ # else /* Solaris, Cygwin, general case */
+@@ -586,7 +648,9 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
+
+ for (;;)
+ {
+- count = acl (name, GETACL, alloc, entries);
++ count = (fd < 0
++ ? acl (name, GETACL, alloc, entries)
++ : facl (fd, GETACL, alloc, entries));
+ if (count < 0 && errno == ENOSPC)
+ {
+ /* Increase the size of the buffer. */
+@@ -657,7 +721,9 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
+
+ for (;;)
+ {
+- count = acl (name, ACE_GETACL, alloc, entries);
++ count = (fd < 0
++ ? acl (name, ACE_GETACL, alloc, entries)
++ : facl (fd, ACE_GETACL, alloc, entries));
+ if (count < 0 && errno == ENOSPC)
+ {
+ /* Increase the size of the buffer. */
+@@ -722,7 +788,9 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
+ struct acl_entry entries[NACLENTRIES];
+ int count;
+
+- count = getacl (name, NACLENTRIES, entries);
++ count = (fd < 0
++ ? getacl (name, NACLENTRIES, entries)
++ : fgetacl (fd, NACLENTRIES, entries));
+
+ if (count < 0)
+ {
+@@ -751,7 +819,8 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
+ {
+ struct stat statbuf;
+
+- if (stat (name, &statbuf) == -1 && errno != EOVERFLOW)
++ if ((fd < 0 ? stat (name, &statbuf) : fstat (fd, &statbuf)) < 0
++ && errno != EOVERFLOW)
+ return -1;
+
+ return acl_nontrivial (count, entries);
+@@ -765,6 +834,7 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
+ struct acl entries[NACLVENTRIES];
+ int count;
+
++ /* Ignore FD, unfortunately. */
+ count = acl ((char *) name, ACL_GET, NACLVENTRIES, entries);
+
+ if (count < 0)
+@@ -809,7 +879,9 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
+ /* The docs say that type being 0 is equivalent to ACL_ANY, but it
+ is not true, in AIX 5.3. */
+ type.u64 = ACL_ANY;
+- if (aclx_get (name, 0, &type, aclbuf, &aclsize, &mode) >= 0)
++ if (0 <= (fd < 0
++ ? aclx_get (name, 0, &type, aclbuf, &aclsize, &mode)
++ : aclx_fget (fd, 0, &type, aclbuf, &aclsize, &mode)))
+ break;
+ if (errno == ENOSYS)
+ return 0;
+@@ -855,7 +927,10 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
+
+ union { struct acl a; char room[4096]; } u;
+
+- if (statacl ((char *) name, STX_NORMAL, &u.a, sizeof (u)) < 0)
++ if ((fd < 0
++ ? statacl ((char *) name, STX_NORMAL, &u.a, sizeof u)
++ : fstatacl (fd, STX_NORMAL, &u.a, sizeof u))
++ < 0)
+ return -1;
+
+ return acl_nontrivial (&u.a);
+@@ -866,6 +941,7 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
+ struct acl entries[NACLENTRIES];
+ int count;
+
++ /* Ignore FD, unfortunately. */
+ count = acl ((char *) name, ACL_GET, NACLENTRIES, entries);
+
+ if (count < 0)
+diff --git a/lib/qcopy-acl.c b/lib/qcopy-acl.c
+index ad7966152a..282f4b2d2a 100644
+--- a/lib/qcopy-acl.c
++++ b/lib/qcopy-acl.c
+@@ -26,6 +26,7 @@
+ #if USE_XATTR
+
+ # include <attr/libattr.h>
++# include <dirent.h>
+ # include <string.h>
+
+ # if HAVE_LINUX_XATTR_H
+@@ -61,6 +62,7 @@ is_attr_permissions (const char *name, struct error_context *ctx)
+ a valid file descriptor, use file descriptor operations, else use
+ filename based operations on SRC_NAME. Likewise for DEST_DESC and
+ DST_NAME.
++ MODE should be the source file's st_mode.
+ If access control lists are not available, fchmod the target file to
+ MODE. Also sets the non-permission bits of the destination file
+ (S_ISUID, S_ISGID, S_ISVTX) to those from MODE if any are set.
+@@ -86,10 +88,29 @@ qcopy_acl (const char *src_name, int source_desc, const char *dst_name,
+ Functions attr_copy_* return 0 in case we copied something OR nothing
+ to copy */
+ if (ret == 0)
+- ret = source_desc <= 0 || dest_desc <= 0
+- ? attr_copy_file (src_name, dst_name, is_attr_permissions, NULL)
+- : attr_copy_fd (src_name, source_desc, dst_name, dest_desc,
+- is_attr_permissions, NULL);
++ {
++ ret = source_desc <= 0 || dest_desc <= 0
++ ? attr_copy_file (src_name, dst_name, is_attr_permissions, NULL)
++ : attr_copy_fd (src_name, source_desc, dst_name, dest_desc,
++ is_attr_permissions, NULL);
++
++ /* Copying can fail with EOPNOTSUPP even when the source
++ permissions are trivial (Bug#78328). Don't report an error
++ in this case, as the chmod_or_fchmod suffices. */
++ if (ret < 0 && errno == EOPNOTSUPP)
++ {
++ /* fdfile_has_aclinfo cares only about DT_DIR, _GL_DT_NOTDIR,
++ and DT_LNK (but DT_LNK is not possible here),
++ so use _GL_DT_NOTDIR | DT_UNKNOWN for other file types. */
++ int flags = S_ISDIR (mode) ? DT_DIR : _GL_DT_NOTDIR | DT_UNKNOWN;
++
++ struct aclinfo ai;
++ if (!fdfile_has_aclinfo (source_desc, src_name, &ai, flags))
++ ret = 0;
++ aclinfo_free (&ai);
++ errno = EOPNOTSUPP;
++ }
++ }
+ #else
+ /* no XATTR, so we proceed the old dusty way */
+ struct permission_context ctx;
diff -Nru coreutils-9.7/debian/patches/series coreutils-9.7/debian/patches/series
--- coreutils-9.7/debian/patches/series 2025-04-08 19:57:40.000000000 +0200
+++ coreutils-9.7/debian/patches/series 2025-06-04 17:12:22.000000000 +0200
@@ -1 +1,2 @@
72_id_checkngroups.patch
+gnulib-nfs-acl.patch
--- End Message ---