Compare commits
4 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
370c5aa4ee |
||
|
|
dfeff61db9 |
||
|
|
808a316567 |
||
|
|
4fbe411873 |
5 changed files with 779 additions and 33 deletions
573
coreutils-9.6-cp-improve-nfsv4-acl-support.patch
Normal file
573
coreutils-9.6-cp-improve-nfsv4-acl-support.patch
Normal file
|
|
@ -0,0 +1,573 @@
|
|||
From 1cddf45cbba44b2afa34291b1b605d39c8cb061c Mon Sep 17 00:00:00 2001
|
||||
From: Paul Eggert <eggert@cs.ucla.edu>
|
||||
Date: Mon, 7 Apr 2025 01:45:17 -0700
|
||||
Subject: [PATCH 1/3] file-has-acl: port symlink code to Cygwin
|
||||
|
||||
Problem reported by Corinna Vinschen in:
|
||||
https://lists.gnu.org/r/bug-gnulib/2025-03/msg00112.html
|
||||
* lib/file-has-acl.c (acl_get_link_np): New static function,
|
||||
defined only if needed; include <fcntl.h> if needed for this.
|
||||
(HAVE_ACL_GET_LINK_NP): Define this if defining acl_get_link_np.
|
||||
|
||||
(cherry picked from commit 41e7b7e0d159d8ac0eb385964119f350ac9dfc3f)
|
||||
---
|
||||
lib/file-has-acl.c | 25 ++++++++++++++++++++++++-
|
||||
1 file changed, 24 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c
|
||||
index c02cfee..59ad9b9 100644
|
||||
--- a/lib/file-has-acl.c
|
||||
+++ b/lib/file-has-acl.c
|
||||
@@ -363,6 +363,29 @@ 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
|
||||
+
|
||||
+/* Like acl_get_file, but do not follow symbolic links. */
|
||||
+static acl_t
|
||||
+acl_get_link_np (char const *name, acl_type_t type)
|
||||
+{
|
||||
+ int fd = open (name, O_PATH | O_NOFOLLOW);
|
||||
+ if (fd < 0)
|
||||
+ return NULL;
|
||||
+ acl_t r = acl_get_fd (fd);
|
||||
+ int err = errno;
|
||||
+ close (fd);
|
||||
+ errno = err;
|
||||
+ return r;
|
||||
+}
|
||||
+# define HAVE_ACL_GET_LINK_NP 1
|
||||
+# endif
|
||||
+#endif
|
||||
+
|
||||
/* Return 1 if 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
|
||||
@@ -468,7 +491,7 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name,
|
||||
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 */
|
||||
+# 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
|
||||
--
|
||||
2.49.0
|
||||
|
||||
From a0e61926b04ff6ec0449607ba306c1b5770660d3 Mon Sep 17 00:00:00 2001
|
||||
From: Paul Eggert <eggert@cs.ucla.edu>
|
||||
Date: Fri, 9 May 2025 18:02:29 -0700
|
||||
Subject: [PATCH 2/3] qcopy-acl: port better to NFSv4 on GNU/Linux
|
||||
|
||||
Problem reported by Ian Dall in <https://bugs.gnu.org/78328>
|
||||
and by Thomas Clark in <https://bugzilla.redhat.com/2363149>.
|
||||
* lib/file-has-acl.c (smack_new_label_from_file) [!HAVE_SMACK]:
|
||||
New dummy function.
|
||||
(has_xattr, get_aclinfo): New arg FD. All callers changed.
|
||||
Remove some unnecessary MAYBE_UNUSEDs.
|
||||
(acl_get_fd_np): Fall back on acl_get_fd if this function is
|
||||
needed but not available.
|
||||
(acl_get_fdfile): New function, if needed.
|
||||
(file_has_aclinfo): Reimplement in terms of ...
|
||||
(fdfile_has_aclinfo): ... this new function,
|
||||
which also has an FD argument.
|
||||
* lib/qcopy-acl.c [USE_XATTR]: Include dirent.h, for DT_DIR etc.
|
||||
(qcopy_acl): If attr_copy_file or attr_copy_fd fail with EOPNOTSUPP,
|
||||
don’t fail if the source has a trivial ACL (this is the part
|
||||
that fixes the bug; the rest is optimization).
|
||||
|
||||
(cherry picked from commit 8a356b77717a2e4f735ec06e326880ca1f61aadb)
|
||||
---
|
||||
lib/acl.h | 2 +
|
||||
lib/copy-acl.c | 1 +
|
||||
lib/file-has-acl.c | 172 ++++++++++++++++++++++++++++++++-------------
|
||||
lib/qcopy-acl.c | 29 ++++++--
|
||||
4 files changed, 152 insertions(+), 52 deletions(-)
|
||||
|
||||
diff --git a/lib/acl.h b/lib/acl.h
|
||||
index 90fd24e..e3c134f 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 c36f64e..2fce6c7 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 59ad9b9..afd951a 100644
|
||||
--- a/lib/file-has-acl.c
|
||||
+++ b/lib/file-has-acl.c
|
||||
@@ -86,6 +86,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)
|
||||
@@ -116,14 +123,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;
|
||||
}
|
||||
@@ -146,11 +155,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;
|
||||
@@ -164,7 +174,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;
|
||||
@@ -172,7 +184,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;
|
||||
@@ -215,9 +229,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;
|
||||
}
|
||||
}
|
||||
@@ -227,8 +245,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
|
||||
@@ -363,11 +383,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
|
||||
@@ -382,8 +404,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,
|
||||
@@ -399,14 +437,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)
|
||||
{
|
||||
@@ -419,11 +478,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,
|
||||
@@ -433,8 +492,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)
|
||||
{
|
||||
@@ -468,20 +529,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);
|
||||
@@ -490,13 +554,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);
|
||||
@@ -518,7 +577,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 */
|
||||
@@ -563,7 +622,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 */
|
||||
@@ -587,7 +649,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. */
|
||||
@@ -658,7 +722,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. */
|
||||
@@ -723,7 +789,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)
|
||||
{
|
||||
@@ -752,7 +820,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);
|
||||
@@ -766,6 +835,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)
|
||||
@@ -810,7 +880,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;
|
||||
@@ -856,7 +928,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);
|
||||
@@ -867,6 +942,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 ad79661..282f4b2 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;
|
||||
--
|
||||
2.49.0
|
||||
|
||||
From 6595a08347c03321e1061ae747f02e4fe67e2073 Mon Sep 17 00:00:00 2001
|
||||
From: Paul Eggert <eggert@cs.ucla.edu>
|
||||
Date: Fri, 9 May 2025 18:48:03 -0700
|
||||
Subject: [PATCH 3/3] acl-tests: link with $(FILE_HAS_ACL_LIB)
|
||||
|
||||
* modules/acl-tests (test_copy_acl_LDADD): Add
|
||||
$(FILE_HAS_ACL_LIB), since qcopy-acl depends on file-has-acl.
|
||||
Although this suggests that QCOPY_ACL_LIB should contain
|
||||
FILE_HAS_ACL_LIB, I’m not sure whether that’s the right course of
|
||||
action and anyway this is good enough for coreutils.
|
||||
|
||||
(cherry picked from commit 955360a66c99bdd9ac3688519a8b521b06958fd3)
|
||||
---
|
||||
gnulib-tests/gnulib.mk | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/gnulib-tests/gnulib.mk b/gnulib-tests/gnulib.mk
|
||||
index eab1c6b..a5fd178 100644
|
||||
--- a/gnulib-tests/gnulib.mk
|
||||
+++ b/gnulib-tests/gnulib.mk
|
||||
@@ -99,7 +99,7 @@ TESTS += \
|
||||
TESTS_ENVIRONMENT += USE_ACL=$(USE_ACL)
|
||||
check_PROGRAMS += test-set-mode-acl test-copy-acl test-sameacls
|
||||
test_set_mode_acl_LDADD = $(LDADD) $(LIB_ACL) $(LIBUNISTRING) @LIBINTL@ $(MBRTOWC_LIB) $(LIBC32CONV)
|
||||
-test_copy_acl_LDADD = $(LDADD) $(LIB_ACL) $(QCOPY_ACL_LIB) $(LIBUNISTRING) @LIBINTL@ $(MBRTOWC_LIB) $(LIBC32CONV)
|
||||
+test_copy_acl_LDADD = $(LDADD) $(LIB_ACL) $(QCOPY_ACL_LIB) $(FILE_HAS_ACL_LIB) $(LIBUNISTRING) @LIBINTL@ $(MBRTOWC_LIB) $(LIBC32CONV)
|
||||
test_sameacls_LDADD = $(LDADD) $(LIB_ACL) @LIBINTL@ $(MBRTOWC_LIB)
|
||||
EXTRA_DIST += test-set-mode-acl.sh test-set-mode-acl-1.sh test-set-mode-acl-2.sh test-copy-acl.sh test-copy-acl-1.sh test-copy-acl-2.sh test-set-mode-acl.c test-copy-acl.c test-sameacls.c macros.h
|
||||
|
||||
--
|
||||
2.49.0
|
||||
|
||||
37
coreutils-9.6-ls-selinux-crash-2.patch
Normal file
37
coreutils-9.6-ls-selinux-crash-2.patch
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
From b54c3d30b0447b69d9bb405d2adb830ae1172dce Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <P@draigBrady.com>
|
||||
Date: Thu, 20 Mar 2025 18:40:01 +0000
|
||||
Subject: [PATCH] ls: fix crash on systems with SELinux but without xattr
|
||||
support
|
||||
|
||||
This was seen on termux on Android with ./configure --disable-xattr
|
||||
where listxattr() and getxattr() returned ENOTSUP.
|
||||
Then the valid security context obtained by file_has_aclinfo()
|
||||
was discounted, and problematically then freed multiple times.
|
||||
Reported at https://github.com/termux/termux-packages/issues/23752
|
||||
|
||||
* src/ls.c (file_has_aclinfo_cache): Only discount the returned
|
||||
acl info when all components are defaulted due to being unsupported.
|
||||
|
||||
(cherry picked from commit cb2abbac7f9e40e0f0d6183bf9b11e80b0cad8ef)
|
||||
---
|
||||
src/ls.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/ls.c b/src/ls.c
|
||||
index f67167f..97cf46a 100644
|
||||
--- a/src/ls.c
|
||||
+++ b/src/ls.c
|
||||
@@ -3322,7 +3322,8 @@ file_has_aclinfo_cache (char const *file, struct fileinfo *f,
|
||||
errno = 0;
|
||||
int n = file_has_aclinfo (file, ai, flags);
|
||||
int err = errno;
|
||||
- if (f->stat_ok && n <= 0 && !acl_errno_valid (err))
|
||||
+ if (f->stat_ok && n <= 0 && !acl_errno_valid (err)
|
||||
+ && (!(flags & ACL_GET_SCONTEXT) || !acl_errno_valid (ai->scontext_err)))
|
||||
{
|
||||
unsupported_return = n;
|
||||
unsupported_scontext = ai->scontext;
|
||||
--
|
||||
2.50.0
|
||||
|
||||
107
coreutils-CVE-2025-5278.patch
Normal file
107
coreutils-CVE-2025-5278.patch
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
From 701a9bdbf78f869e0fb778ed5aede00e42517add Mon Sep 17 00:00:00 2001
|
||||
From: Pádraig Brady <P@draigBrady.com>
|
||||
Date: Tue, 20 May 2025 16:03:44 +0100
|
||||
Subject: [PATCH] sort: fix buffer under-read (CWE-127)
|
||||
|
||||
* src/sort.c (begfield): Check pointer adjustment
|
||||
to avoid Out-of-range pointer offset (CWE-823).
|
||||
(limfield): Likewise.
|
||||
* tests/sort/sort-field-limit.sh: Add a new test,
|
||||
which triggers with ASAN or Valgrind.
|
||||
* tests/local.mk: Reference the new test.
|
||||
Fixes https://bugs.gnu.org/78507
|
||||
|
||||
(cherry picked from commit 8c9602e3a145e9596dc1a63c6ed67865814b6633)
|
||||
---
|
||||
src/sort.c | 12 ++++++++++--
|
||||
tests/local.mk | 1 +
|
||||
tests/sort/sort-field-limit.sh | 35 ++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 46 insertions(+), 2 deletions(-)
|
||||
create mode 100755 tests/sort/sort-field-limit.sh
|
||||
|
||||
diff --git a/src/sort.c b/src/sort.c
|
||||
index b10183b..7af1a25 100644
|
||||
--- a/src/sort.c
|
||||
+++ b/src/sort.c
|
||||
@@ -1644,7 +1644,11 @@ begfield (struct line const *line, struct keyfield const *key)
|
||||
++ptr;
|
||||
|
||||
/* Advance PTR by SCHAR (if possible), but no further than LIM. */
|
||||
- ptr = MIN (lim, ptr + schar);
|
||||
+ size_t remaining_bytes = lim - ptr;
|
||||
+ if (schar < remaining_bytes)
|
||||
+ ptr += schar;
|
||||
+ else
|
||||
+ ptr = lim;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
@@ -1746,7 +1750,11 @@ limfield (struct line const *line, struct keyfield const *key)
|
||||
++ptr;
|
||||
|
||||
/* Advance PTR by ECHAR (if possible), but no further than LIM. */
|
||||
- ptr = MIN (lim, ptr + echar);
|
||||
+ size_t remaining_bytes = lim - ptr;
|
||||
+ if (echar < remaining_bytes)
|
||||
+ ptr += echar;
|
||||
+ else
|
||||
+ ptr = lim;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
diff --git a/tests/local.mk b/tests/local.mk
|
||||
index 4da6756..642d225 100644
|
||||
--- a/tests/local.mk
|
||||
+++ b/tests/local.mk
|
||||
@@ -388,6 +388,7 @@ all_tests = \
|
||||
tests/sort/sort-debug-keys.sh \
|
||||
tests/sort/sort-debug-warn.sh \
|
||||
tests/sort/sort-discrim.sh \
|
||||
+ tests/sort/sort-field-limit.sh \
|
||||
tests/sort/sort-files0-from.pl \
|
||||
tests/sort/sort-float.sh \
|
||||
tests/sort/sort-h-thousands-sep.sh \
|
||||
diff --git a/tests/sort/sort-field-limit.sh b/tests/sort/sort-field-limit.sh
|
||||
new file mode 100755
|
||||
index 0000000..52d8e1d
|
||||
--- /dev/null
|
||||
+++ b/tests/sort/sort-field-limit.sh
|
||||
@@ -0,0 +1,35 @@
|
||||
+#!/bin/sh
|
||||
+# From 7.2-9.7, this would trigger an out of bounds mem read
|
||||
+
|
||||
+# Copyright (C) 2025 Free Software Foundation, Inc.
|
||||
+
|
||||
+# This program is free software: you can redistribute it and/or modify
|
||||
+# it under the terms of the GNU General Public License as published by
|
||||
+# the Free Software Foundation, either version 3 of the License, or
|
||||
+# (at your option) any later version.
|
||||
+
|
||||
+# This program is distributed in the hope that it will be useful,
|
||||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+# GNU General Public License for more details.
|
||||
+
|
||||
+# You should have received a copy of the GNU General Public License
|
||||
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
+
|
||||
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
|
||||
+print_ver_ sort
|
||||
+getlimits_
|
||||
+
|
||||
+# This issue triggers with valgrind or ASAN
|
||||
+valgrind --error-exitcode=1 sort --version 2>/dev/null &&
|
||||
+ VALGRIND='valgrind --error-exitcode=1'
|
||||
+
|
||||
+{ printf '%s\n' aa bb; } > in || framework_failure_
|
||||
+
|
||||
+_POSIX2_VERSION=200809 $VALGRIND sort +0.${SIZE_MAX}R in > out || fail=1
|
||||
+compare in out || fail=1
|
||||
+
|
||||
+_POSIX2_VERSION=200809 $VALGRIND sort +1 -1.${SIZE_MAX}R in > out || fail=1
|
||||
+compare in out || fail=1
|
||||
+
|
||||
+Exit $fail
|
||||
--
|
||||
2.49.0
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
From a153c65067f6c09cf2cf38dc7c149aa1521c615a Mon Sep 17 00:00:00 2001
|
||||
From 26b941130b4bba79d1b3e5cf0c352a0887c97d80 Mon Sep 17 00:00:00 2001
|
||||
From: rpm-build <rpm-build>
|
||||
Date: Wed, 30 Aug 2023 17:19:58 +0200
|
||||
Subject: [PATCH] coreutils-i18n.patch
|
||||
|
|
@ -3008,7 +3008,7 @@ index e7081a0..19e0268 100644
|
|||
looking for more options and printing the next batch of files.
|
||||
|
||||
diff --git a/src/sort.c b/src/sort.c
|
||||
index 0928fd5..8c43fd4 100644
|
||||
index d059826..132f9bc 100644
|
||||
--- a/src/sort.c
|
||||
+++ b/src/sort.c
|
||||
@@ -29,6 +29,14 @@
|
||||
|
|
@ -3265,7 +3265,7 @@ index 0928fd5..8c43fd4 100644
|
|||
++ptr;
|
||||
if (ptr < lim)
|
||||
++ptr;
|
||||
@@ -1650,12 +1799,71 @@ begfield (struct line const *line, struct keyfield const *key)
|
||||
@@ -1654,12 +1803,71 @@ begfield (struct line const *line, struct keyfield const *key)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
|
@ -3338,7 +3338,7 @@ index 0928fd5..8c43fd4 100644
|
|||
{
|
||||
char *ptr = line->text, *lim = ptr + line->length - 1;
|
||||
size_t eword = key->eword, echar = key->echar;
|
||||
@@ -1670,10 +1878,10 @@ limfield (struct line const *line, struct keyfield const *key)
|
||||
@@ -1674,10 +1882,10 @@ limfield (struct line const *line, struct keyfield const *key)
|
||||
'beginning' is the first character following the delimiting TAB.
|
||||
Otherwise, leave PTR pointing at the first 'blank' character after
|
||||
the preceding field. */
|
||||
|
|
@ -3351,7 +3351,7 @@ index 0928fd5..8c43fd4 100644
|
|||
++ptr;
|
||||
if (ptr < lim && (eword || echar))
|
||||
++ptr;
|
||||
@@ -1719,10 +1927,10 @@ limfield (struct line const *line, struct keyfield const *key)
|
||||
@@ -1723,10 +1931,10 @@ limfield (struct line const *line, struct keyfield const *key)
|
||||
*/
|
||||
|
||||
/* Make LIM point to the end of (one byte past) the current field. */
|
||||
|
|
@ -3364,7 +3364,7 @@ index 0928fd5..8c43fd4 100644
|
|||
if (newlim)
|
||||
lim = newlim;
|
||||
}
|
||||
@@ -1753,6 +1961,130 @@ limfield (struct line const *line, struct keyfield const *key)
|
||||
@@ -1761,6 +1969,130 @@ limfield (struct line const *line, struct keyfield const *key)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
|
@ -3495,7 +3495,7 @@ index 0928fd5..8c43fd4 100644
|
|||
/* Fill BUF reading from FP, moving buf->left bytes from the end
|
||||
of buf->buf to the beginning first. If EOF is reached and the
|
||||
file wasn't terminated by a newline, supply one. Set up BUF's line
|
||||
@@ -1839,8 +2171,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file)
|
||||
@@ -1847,8 +2179,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file)
|
||||
else
|
||||
{
|
||||
if (key->skipsblanks)
|
||||
|
|
@ -3520,7 +3520,7 @@ index 0928fd5..8c43fd4 100644
|
|||
line->keybeg = line_start;
|
||||
}
|
||||
}
|
||||
@@ -1978,12 +2324,10 @@ find_unit_order (char const *number)
|
||||
@@ -1986,12 +2332,10 @@ find_unit_order (char const *number)
|
||||
|
||||
ATTRIBUTE_PURE
|
||||
static int
|
||||
|
|
@ -3536,7 +3536,7 @@ index 0928fd5..8c43fd4 100644
|
|||
|
||||
int diff = find_unit_order (a) - find_unit_order (b);
|
||||
return (diff ? diff : strnumcmp (a, b, decimal_point, thousands_sep));
|
||||
@@ -1995,7 +2339,7 @@ human_numcompare (char const *a, char const *b)
|
||||
@@ -2003,7 +2347,7 @@ human_numcompare (char const *a, char const *b)
|
||||
|
||||
ATTRIBUTE_PURE
|
||||
static int
|
||||
|
|
@ -3545,7 +3545,7 @@ index 0928fd5..8c43fd4 100644
|
|||
{
|
||||
while (blanks[to_uchar (*a)])
|
||||
a++;
|
||||
@@ -2005,6 +2349,25 @@ numcompare (char const *a, char const *b)
|
||||
@@ -2013,6 +2357,25 @@ numcompare (char const *a, char const *b)
|
||||
return strnumcmp (a, b, decimal_point, thousands_sep);
|
||||
}
|
||||
|
||||
|
|
@ -3571,7 +3571,7 @@ index 0928fd5..8c43fd4 100644
|
|||
static int
|
||||
nan_compare (long double a, long double b)
|
||||
{
|
||||
@@ -2046,7 +2409,7 @@ general_numcompare (char const *sa, char const *sb)
|
||||
@@ -2054,7 +2417,7 @@ general_numcompare (char const *sa, char const *sb)
|
||||
Return 0 if the name in S is not recognized. */
|
||||
|
||||
static int
|
||||
|
|
@ -3580,7 +3580,7 @@ index 0928fd5..8c43fd4 100644
|
|||
{
|
||||
size_t lo = 0;
|
||||
size_t hi = MONTHS_PER_YEAR;
|
||||
@@ -2385,15 +2748,14 @@ debug_key (struct line const *line, struct keyfield const *key)
|
||||
@@ -2393,15 +2756,14 @@ debug_key (struct line const *line, struct keyfield const *key)
|
||||
char saved = *lim;
|
||||
*lim = '\0';
|
||||
|
||||
|
|
@ -3598,7 +3598,7 @@ index 0928fd5..8c43fd4 100644
|
|||
else if (key->general_numeric)
|
||||
ignore_value (strtold (beg, &tighter_lim));
|
||||
else if (key->numeric || key->human_numeric)
|
||||
@@ -2539,7 +2901,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only)
|
||||
@@ -2547,7 +2909,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only)
|
||||
/* Warn about significant leading blanks. */
|
||||
bool implicit_skip = key_numeric (key) || key->month;
|
||||
bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */
|
||||
|
|
@ -3607,7 +3607,7 @@ index 0928fd5..8c43fd4 100644
|
|||
&& ((!key->skipsblanks && !implicit_skip)
|
||||
|| (!key->skipsblanks && key->schar)
|
||||
|| (!key->skipeblanks && key->echar)))
|
||||
@@ -2587,9 +2949,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only)
|
||||
@@ -2595,9 +2957,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only)
|
||||
bool number_locale_warned = false;
|
||||
if (basic_numeric_field_span)
|
||||
{
|
||||
|
|
@ -3620,7 +3620,7 @@ index 0928fd5..8c43fd4 100644
|
|||
{
|
||||
error (0, 0,
|
||||
_("field separator %s is treated as a "
|
||||
@@ -2600,9 +2962,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only)
|
||||
@@ -2608,9 +2970,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only)
|
||||
}
|
||||
if (basic_numeric_field_span || general_numeric_field_span)
|
||||
{
|
||||
|
|
@ -3633,7 +3633,7 @@ index 0928fd5..8c43fd4 100644
|
|||
{
|
||||
error (0, 0,
|
||||
_("field separator %s is treated as a "
|
||||
@@ -2610,19 +2972,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only)
|
||||
@@ -2618,19 +2980,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only)
|
||||
quote (((char []) {decimal_point, 0})));
|
||||
number_locale_warned = true;
|
||||
}
|
||||
|
|
@ -3657,7 +3657,7 @@ index 0928fd5..8c43fd4 100644
|
|||
}
|
||||
}
|
||||
|
||||
@@ -2633,7 +2995,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only)
|
||||
@@ -2641,7 +3003,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only)
|
||||
{
|
||||
error (0, 0,
|
||||
_("%snumbers use %s as a decimal point in this locale"),
|
||||
|
|
@ -3666,7 +3666,7 @@ index 0928fd5..8c43fd4 100644
|
|||
quote (((char []) {decimal_point, 0})));
|
||||
|
||||
}
|
||||
@@ -2675,11 +3037,87 @@ diff_reversed (int diff, bool reversed)
|
||||
@@ -2683,11 +3045,87 @@ diff_reversed (int diff, bool reversed)
|
||||
return reversed ? (diff < 0) - (diff > 0) : diff;
|
||||
}
|
||||
|
||||
|
|
@ -3755,7 +3755,7 @@ index 0928fd5..8c43fd4 100644
|
|||
{
|
||||
struct keyfield *key = keylist;
|
||||
|
||||
@@ -2760,7 +3198,7 @@ keycompare (struct line const *a, struct line const *b)
|
||||
@@ -2768,7 +3206,7 @@ keycompare (struct line const *a, struct line const *b)
|
||||
else if (key->human_numeric)
|
||||
diff = human_numcompare (ta, tb);
|
||||
else if (key->month)
|
||||
|
|
@ -3764,7 +3764,7 @@ index 0928fd5..8c43fd4 100644
|
|||
else if (key->random)
|
||||
diff = compare_random (ta, tlena, tb, tlenb);
|
||||
else if (key->version)
|
||||
@@ -2870,6 +3308,211 @@ keycompare (struct line const *a, struct line const *b)
|
||||
@@ -2878,6 +3316,211 @@ keycompare (struct line const *a, struct line const *b)
|
||||
return diff_reversed (diff, key->reverse);
|
||||
}
|
||||
|
||||
|
|
@ -3976,7 +3976,7 @@ index 0928fd5..8c43fd4 100644
|
|||
/* Compare two lines A and B, returning negative, zero, or positive
|
||||
depending on whether A compares less than, equal to, or greater than B. */
|
||||
|
||||
@@ -2897,7 +3540,7 @@ compare (struct line const *a, struct line const *b)
|
||||
@@ -2905,7 +3548,7 @@ compare (struct line const *a, struct line const *b)
|
||||
diff = - NONZERO (blen);
|
||||
else if (blen == 0)
|
||||
diff = 1;
|
||||
|
|
@ -3985,7 +3985,7 @@ index 0928fd5..8c43fd4 100644
|
|||
{
|
||||
/* xmemcoll0 is a performance enhancement as
|
||||
it will not unconditionally write '\0' after the
|
||||
@@ -4285,6 +4928,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype)
|
||||
@@ -4293,6 +4936,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype)
|
||||
break;
|
||||
case 'f':
|
||||
key->translate = fold_toupper;
|
||||
|
|
@ -3993,7 +3993,7 @@ index 0928fd5..8c43fd4 100644
|
|||
break;
|
||||
case 'g':
|
||||
key->general_numeric = true;
|
||||
@@ -4364,7 +5008,7 @@ main (int argc, char **argv)
|
||||
@@ -4372,7 +5016,7 @@ main (int argc, char **argv)
|
||||
initialize_exit_failure (SORT_FAILURE);
|
||||
|
||||
hard_LC_COLLATE = hard_locale (LC_COLLATE);
|
||||
|
|
@ -4002,7 +4002,7 @@ index 0928fd5..8c43fd4 100644
|
|||
hard_LC_TIME = hard_locale (LC_TIME);
|
||||
#endif
|
||||
|
||||
@@ -4387,6 +5031,29 @@ main (int argc, char **argv)
|
||||
@@ -4395,6 +5039,29 @@ main (int argc, char **argv)
|
||||
thousands_sep = NON_CHAR;
|
||||
}
|
||||
|
||||
|
|
@ -4032,7 +4032,7 @@ index 0928fd5..8c43fd4 100644
|
|||
have_read_stdin = false;
|
||||
inittables ();
|
||||
|
||||
@@ -4657,13 +5324,34 @@ main (int argc, char **argv)
|
||||
@@ -4665,13 +5332,34 @@ main (int argc, char **argv)
|
||||
|
||||
case 't':
|
||||
{
|
||||
|
|
@ -4071,7 +4071,7 @@ index 0928fd5..8c43fd4 100644
|
|||
else
|
||||
{
|
||||
/* Provoke with 'sort -txx'. Complain about
|
||||
@@ -4674,9 +5362,11 @@ main (int argc, char **argv)
|
||||
@@ -4682,9 +5370,11 @@ main (int argc, char **argv)
|
||||
quote (optarg));
|
||||
}
|
||||
}
|
||||
|
|
@ -4528,11 +4528,11 @@ index 0000000..26c95de
|
|||
+
|
||||
+Exit $fail
|
||||
diff --git a/tests/local.mk b/tests/local.mk
|
||||
index 12e30b4..1529db6 100644
|
||||
index 864cd16..eb898ab 100644
|
||||
--- a/tests/local.mk
|
||||
+++ b/tests/local.mk
|
||||
@@ -390,6 +390,8 @@ all_tests = \
|
||||
tests/sort/sort-discrim.sh \
|
||||
@@ -391,6 +391,8 @@ all_tests = \
|
||||
tests/sort/sort-field-limit.sh \
|
||||
tests/sort/sort-files0-from.pl \
|
||||
tests/sort/sort-float.sh \
|
||||
+ tests/misc/sort-mb-tests.sh \
|
||||
|
|
@ -4540,7 +4540,7 @@ index 12e30b4..1529db6 100644
|
|||
tests/sort/sort-h-thousands-sep.sh \
|
||||
tests/sort/sort-merge.pl \
|
||||
tests/sort/sort-merge-fdlimit.sh \
|
||||
@@ -593,6 +595,7 @@ all_tests = \
|
||||
@@ -594,6 +596,7 @@ all_tests = \
|
||||
tests/du/threshold.sh \
|
||||
tests/du/trailing-slash.sh \
|
||||
tests/du/two-args.sh \
|
||||
|
|
@ -4548,7 +4548,7 @@ index 12e30b4..1529db6 100644
|
|||
tests/id/gnu-zero-uids.sh \
|
||||
tests/id/no-context.sh \
|
||||
tests/id/context.sh \
|
||||
@@ -749,6 +752,7 @@ all_tests = \
|
||||
@@ -750,6 +753,7 @@ all_tests = \
|
||||
tests/touch/read-only.sh \
|
||||
tests/touch/relative.sh \
|
||||
tests/touch/trailing-slash.sh \
|
||||
|
|
@ -5180,5 +5180,5 @@ index 0000000..8a82d74
|
|||
+LC_ALL=C unexpand in in > out || fail=1
|
||||
+compare exp out > /dev/null 2>&1 || fail=1
|
||||
--
|
||||
2.48.1
|
||||
2.49.0
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
Summary: A set of basic GNU tools commonly used in shell scripts
|
||||
Name: coreutils
|
||||
Version: 9.6
|
||||
Release: 2%{?dist}
|
||||
Release: 6%{?dist}
|
||||
# some used parts of gnulib are under various variants of LGPL
|
||||
License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later
|
||||
Url: https://www.gnu.org/software/coreutils/
|
||||
|
|
@ -40,6 +40,20 @@ Patch105: coreutils-9.6-ls-selinux-crash.patch
|
|||
# https://git.savannah.gnu.org/cgit/coreutils.git/patch/?id=24450e5eecf012bc1ea8cab8d677a45fa42c1778
|
||||
Patch106: coreutils-9.6-who-m-systemd.patch
|
||||
|
||||
# cp/mv: do not fail when copying of trivial NFSv4 ACLs fails (rhbz#2363149)
|
||||
# https://git.savannah.gnu.org/cgit/gnulib.git/patch?id=41e7b7e0d159d8ac0eb385964119f350ac9dfc3f
|
||||
# https://git.savannah.gnu.org/cgit/gnulib.git/patch?id=8a356b77717a2e4f735ec06e326880ca1f61aadb
|
||||
# https://git.savannah.gnu.org/cgit/gnulib.git/patch?id=955360a66c99bdd9ac3688519a8b521b06958fd3
|
||||
Patch107: coreutils-9.6-cp-improve-nfsv4-acl-support.patch
|
||||
|
||||
# sort: fix buffer under-read (CVE-2025-5278)
|
||||
# https://cgit.git.savannah.gnu.org/cgit/coreutils.git/patch/?id=8c9602e3a145e9596dc1a63c6ed67865814b6633
|
||||
Patch108: coreutils-CVE-2025-5278.patch
|
||||
|
||||
# ls: fix crash on systems with SELinux but without xattr support (rhbz#2376721)
|
||||
# https://cgit.git.savannah.gnu.org/cgit/coreutils.git/patch/?id=cb2abbac7f9e40e0f0d6183bf9b11e80b0cad8ef
|
||||
Patch109: coreutils-9.6-ls-selinux-crash-2.patch
|
||||
|
||||
# (sb) lin18nux/lsb compliance - multibyte functionality patch
|
||||
Patch800: coreutils-i18n.patch
|
||||
|
||||
|
|
@ -128,6 +142,9 @@ packaged as a single multicall binary.
|
|||
# https://bugzilla.redhat.com/show_bug.cgi?id=1107973#c7
|
||||
Obsoletes: %{name} < 8.24-100
|
||||
|
||||
# Gnulib translations are maintained seprately since coreutils 9.6 (#2393892)
|
||||
Requires: gnulib-l10n
|
||||
|
||||
# info doc refers to "Specifying the Time Zone" from glibc-doc (#959597)
|
||||
Suggests: glibc-doc
|
||||
|
||||
|
|
@ -286,6 +303,18 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir
|
|||
%license COPYING
|
||||
|
||||
%changelog
|
||||
* Mon Sep 29 2025 Lukáš Zaoral <lzaoral@redhat.com> - 9.6-6
|
||||
- require gnulib-l10n for translations of gnulib messages (rhbz#2393892)
|
||||
|
||||
* Tue Jul 08 2025 Lukáš Zaoral <lzaoral@redhat.com> - 9.6-5
|
||||
- ls: fix crash on systems with SELinux but without xattr support (rhbz#2376721)
|
||||
|
||||
* Wed May 28 2025 Lukáš Zaoral <lzaoral@redhat.com> - 9.6-4
|
||||
- sort: fix buffer under-read (CVE-2025-5278)
|
||||
|
||||
* Mon May 19 2025 Lukáš Zaoral <lzaoral@redhat.com> - 9.6-3
|
||||
- cp/mv: do not fail when copying of trivial NFSv4 ACLs fails (rhbz#2363149)
|
||||
|
||||
* Tue Feb 25 2025 Lukáš Zaoral <lzaoral@redhat.com> - 9.6-2
|
||||
- fix 'who -m' with guessed tty names (rhbz#2343998)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue