fix cp -p not copying NFSv4 acls
Resolves: rhbz#2160675
This commit is contained in:
parent
9225dbfda4
commit
effc4950ac
2 changed files with 225 additions and 1 deletions
217
coreutils-9.3-cp--p-should-copy-NFSv4-acls.patch
Normal file
217
coreutils-9.3-cp--p-should-copy-NFSv4-acls.patch
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
commit ccda8a2aedad84d9b730fdd6b36baa9582f54bfd
|
||||
Author: rpm-build <rpm-build>
|
||||
Date: Mon Sep 11 14:28:05 2023 +0200
|
||||
|
||||
coreutils-9.3-cp--p-should-copy-NFSv4-acls.patch
|
||||
|
||||
Cherry picked from the following gnulib upstream commits:
|
||||
* b851a965da62cd858d71b2e5a7261a211f00b297 ("file-has-acl: port to Fedora 39")
|
||||
* f01d8792778b637f7464533ac019e42f58adb310 ("file-has-acl: don’t access freed storage")
|
||||
* 735716931755c74f3788ac83fead717c0bb22dfe ("file-has-acl: improve port to Fedora 39")
|
||||
|
||||
diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c
|
||||
index b31a2ea..4cddc80 100644
|
||||
--- a/lib/file-has-acl.c
|
||||
+++ b/lib/file-has-acl.c
|
||||
@@ -29,7 +29,10 @@
|
||||
|
||||
#include "acl-internal.h"
|
||||
|
||||
-#if USE_ACL && GETXATTR_WITH_POSIX_ACLS
|
||||
+#include "minmax.h"
|
||||
+
|
||||
+#if USE_ACL && HAVE_LINUX_XATTR_H && HAVE_LISTXATTR
|
||||
+# include <stdckdint.h>
|
||||
# include <string.h>
|
||||
# include <arpa/inet.h>
|
||||
# include <sys/xattr.h>
|
||||
@@ -44,6 +47,20 @@ enum {
|
||||
ACE4_IDENTIFIER_GROUP = 0x00000040
|
||||
};
|
||||
|
||||
+/* Return true if ATTR is in the set represented by the NUL-terminated
|
||||
+ strings in LISTBUF, which is of size LISTSIZE. */
|
||||
+
|
||||
+static bool
|
||||
+have_xattr (char const *attr, char const *listbuf, ssize_t listsize)
|
||||
+{
|
||||
+ char const *blim = listbuf + listsize;
|
||||
+ for (char const *b = listbuf; b < blim; b += strlen (b) + 1)
|
||||
+ for (char const *a = attr; *a == *b; a++, b++)
|
||||
+ if (!*a)
|
||||
+ return true;
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
/* Return 1 if given ACL in XDR format is non-trivial, 0 if it is trivial.
|
||||
-1 upon failure to determine it. Possibly change errno. Assume that
|
||||
the ACL is valid, except avoid undefined behavior even if invalid.
|
||||
@@ -137,37 +154,77 @@ file_has_acl (char const *name, struct stat const *sb)
|
||||
if (! S_ISLNK (sb->st_mode))
|
||||
{
|
||||
|
||||
-# if GETXATTR_WITH_POSIX_ACLS
|
||||
-
|
||||
- ssize_t ret;
|
||||
+# if HAVE_LINUX_XATTR_H && HAVE_LISTXATTR
|
||||
int initial_errno = errno;
|
||||
|
||||
- ret = getxattr (name, XATTR_NAME_POSIX_ACL_ACCESS, NULL, 0);
|
||||
- if (ret < 0 && errno == ENODATA)
|
||||
- ret = 0;
|
||||
- else if (ret > 0)
|
||||
- return 1;
|
||||
-
|
||||
- if (ret == 0 && S_ISDIR (sb->st_mode))
|
||||
+ /* The max length of a trivial NFSv4 ACL is 6 words for owner,
|
||||
+ 6 for group, 7 for everyone, all times 2 because there are
|
||||
+ both allow and deny ACEs. There are 6 words for owner
|
||||
+ because of type, flag, mask, wholen, "OWNER@"+pad and
|
||||
+ similarly for group; everyone is another word to hold
|
||||
+ "EVERYONE@". */
|
||||
+ typedef uint32_t trivial_NFSv4_xattr_buf[2 * (6 + 6 + 7)];
|
||||
+
|
||||
+ /* A buffer large enough to hold any trivial NFSv4 ACL,
|
||||
+ and also useful as a small array of char. */
|
||||
+ union {
|
||||
+ trivial_NFSv4_xattr_buf xattr;
|
||||
+ char ch[sizeof (trivial_NFSv4_xattr_buf)];
|
||||
+ } stackbuf;
|
||||
+
|
||||
+ char *listbuf = stackbuf.ch;
|
||||
+ ssize_t listbufsize = sizeof stackbuf.ch;
|
||||
+ char *heapbuf = NULL;
|
||||
+ ssize_t listsize;
|
||||
+
|
||||
+ /* Use listxattr first, as this means just one syscall in the
|
||||
+ typical case where the file lacks an ACL. Try stackbuf
|
||||
+ first, falling back on malloc if stackbuf is too small. */
|
||||
+ while ((listsize = listxattr (name, listbuf, listbufsize)) < 0
|
||||
+ && errno == ERANGE)
|
||||
{
|
||||
- ret = getxattr (name, XATTR_NAME_POSIX_ACL_DEFAULT, NULL, 0);
|
||||
- if (ret < 0 && errno == ENODATA)
|
||||
- ret = 0;
|
||||
- else if (ret > 0)
|
||||
- return 1;
|
||||
+ free (heapbuf);
|
||||
+ ssize_t newsize = listxattr (name, NULL, 0);
|
||||
+ if (newsize <= 0)
|
||||
+ return newsize;
|
||||
+
|
||||
+ /* Grow LISTBUFSIZE to at least NEWSIZE. Grow it by a
|
||||
+ nontrivial amount too, to defend against denial of
|
||||
+ service by an adversary that fiddles with ACLs. */
|
||||
+ bool overflow = ckd_add (&listbufsize, listbufsize, listbufsize >> 1);
|
||||
+ listbufsize = MAX (listbufsize, newsize);
|
||||
+ if (overflow || SIZE_MAX < listbufsize)
|
||||
+ {
|
||||
+ errno = ENOMEM;
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ listbuf = heapbuf = malloc (listbufsize);
|
||||
+ if (!listbuf)
|
||||
+ return -1;
|
||||
}
|
||||
|
||||
- if (ret < 0)
|
||||
+ /* In Fedora 39, a file can have both NFSv4 and POSIX ACLs,
|
||||
+ but if it has an NFSv4 ACL that's the one that matters.
|
||||
+ In earlier Fedora the two types of ACLs were mutually exclusive.
|
||||
+ Attempt to work correctly on both kinds of systems. */
|
||||
+ bool nfsv4_acl
|
||||
+ = 0 < listsize && have_xattr (XATTR_NAME_NFSV4_ACL, listbuf, listsize);
|
||||
+ int ret
|
||||
+ = (listsize <= 0 ? listsize
|
||||
+ : (nfsv4_acl
|
||||
+ || have_xattr (XATTR_NAME_POSIX_ACL_ACCESS, listbuf, listsize)
|
||||
+ || (S_ISDIR (sb->st_mode)
|
||||
+ && have_xattr (XATTR_NAME_POSIX_ACL_DEFAULT,
|
||||
+ listbuf, listsize))));
|
||||
+ free (heapbuf);
|
||||
+
|
||||
+ /* If there is an NFSv4 ACL, follow up with a getxattr syscall
|
||||
+ to see whether the NFSv4 ACL is nontrivial. */
|
||||
+ if (nfsv4_acl)
|
||||
{
|
||||
- /* Check for NFSv4 ACLs. The max length of a trivial
|
||||
- ACL is 6 words for owner, 6 for group, 7 for everyone,
|
||||
- all times 2 because there are both allow and deny ACEs.
|
||||
- There are 6 words for owner because of type, flag, mask,
|
||||
- wholen, "OWNER@"+pad and similarly for group; everyone is
|
||||
- another word to hold "EVERYONE@". */
|
||||
- uint32_t xattr[2 * (6 + 6 + 7)];
|
||||
-
|
||||
- ret = getxattr (name, XATTR_NAME_NFSV4_ACL, xattr, sizeof xattr);
|
||||
+ ret = getxattr (name, XATTR_NAME_NFSV4_ACL,
|
||||
+ stackbuf.xattr, sizeof stackbuf.xattr);
|
||||
if (ret < 0)
|
||||
switch (errno)
|
||||
{
|
||||
@@ -177,7 +234,7 @@ file_has_acl (char const *name, struct stat const *sb)
|
||||
else
|
||||
{
|
||||
/* It looks like a trivial ACL, but investigate further. */
|
||||
- ret = acl_nfs4_nontrivial (xattr, ret);
|
||||
+ ret = acl_nfs4_nontrivial (stackbuf.xattr, ret);
|
||||
if (ret < 0)
|
||||
{
|
||||
errno = EINVAL;
|
||||
diff --git a/m4/acl.m4 b/m4/acl.m4
|
||||
index dc9853a..3fa0779 100644
|
||||
--- a/m4/acl.m4
|
||||
+++ b/m4/acl.m4
|
||||
@@ -177,37 +177,23 @@ AC_DEFUN([gl_ACL_GET_FILE],
|
||||
AS_IF([test "$gl_cv_func_working_acl_get_file" != no], [$1], [$2])
|
||||
])
|
||||
|
||||
-# On GNU/Linux, testing if a file has an acl can be done with the getxattr
|
||||
-# syscall which doesn't require linking against additional libraries.
|
||||
+# On GNU/Linux, testing if a file has an acl can be done with the
|
||||
+# listxattr and getxattr syscalls, which don't require linking
|
||||
+# against additional libraries. Assume this works if linux/attr.h
|
||||
+# and listxattr are present.
|
||||
AC_DEFUN([gl_FILE_HAS_ACL],
|
||||
[
|
||||
AC_REQUIRE([gl_FUNC_ACL_ARG])
|
||||
- if test "$enable_acl" != no; then
|
||||
- AC_CACHE_CHECK([for getxattr with XATTR_NAME_POSIX_ACL macros],
|
||||
- [gl_cv_getxattr_with_posix_acls],
|
||||
- [gl_cv_getxattr_with_posix_acls=no
|
||||
- AC_LINK_IFELSE(
|
||||
- [AC_LANG_PROGRAM(
|
||||
- [[#include <sys/types.h>
|
||||
- #include <sys/xattr.h>
|
||||
- #include <linux/xattr.h>
|
||||
- ]],
|
||||
- [[ssize_t a = getxattr (".", XATTR_NAME_POSIX_ACL_ACCESS, 0, 0);
|
||||
- ssize_t b = getxattr (".", XATTR_NAME_POSIX_ACL_DEFAULT, 0, 0);
|
||||
- return a < 0 || b < 0;
|
||||
- ]])],
|
||||
- [gl_cv_getxattr_with_posix_acls=yes])])
|
||||
- fi
|
||||
- if test "$gl_cv_getxattr_with_posix_acls" = yes; then
|
||||
- FILE_HAS_ACL_LIB=
|
||||
- AC_DEFINE([GETXATTR_WITH_POSIX_ACLS], 1,
|
||||
- [Define to 1 if getxattr works with XATTR_NAME_POSIX_ACL_ACCESS
|
||||
- and XATTR_NAME_POSIX_ACL_DEFAULT.])
|
||||
- else
|
||||
- dnl Set gl_need_lib_has_acl to a nonempty value, so that any
|
||||
- dnl later gl_FUNC_ACL call will set FILE_HAS_ACL_LIB=$LIB_ACL.
|
||||
- gl_need_lib_has_acl=1
|
||||
- FILE_HAS_ACL_LIB=$LIB_ACL
|
||||
- fi
|
||||
+ AC_CHECK_HEADERS_ONCE([linux/xattr.h])
|
||||
+ AC_CHECK_FUNCS_ONCE([listxattr])
|
||||
+ FILE_HAS_ACL_LIB=
|
||||
+ AS_CASE([$enable_acl,$ac_cv_header_linux_xattr_h,$ac_cv_func_listxattr],
|
||||
+ [no,*,*], [],
|
||||
+ [*,yes,yes], [],
|
||||
+ [*],
|
||||
+ [dnl Set gl_need_lib_has_acl to a nonempty value, so that any
|
||||
+ dnl later gl_FUNC_ACL call will set FILE_HAS_ACL_LIB=$LIB_ACL.
|
||||
+ gl_need_lib_has_acl=1
|
||||
+ FILE_HAS_ACL_LIB=$LIB_ACL])
|
||||
AC_SUBST([FILE_HAS_ACL_LIB])
|
||||
])
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
Summary: A set of basic GNU tools commonly used in shell scripts
|
||||
Name: coreutils
|
||||
Version: 9.3
|
||||
Release: 3%{?dist}
|
||||
Release: 4%{?dist}
|
||||
License: GPL-3.0-or-later
|
||||
Url: https://www.gnu.org/software/coreutils/
|
||||
Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz
|
||||
|
|
@ -35,6 +35,10 @@ Patch104: coreutils-df-direct.patch
|
|||
# backport of cc078f747f3db00e70b2ae2ad2ab34e8d54316d3.
|
||||
Patch105: coreutils-9.3-reduce--iu-verbosity-with-verbose.patch
|
||||
|
||||
# cp -p should copy NFSv4 acls (#2160675)
|
||||
# see the patch for the list of backported commits
|
||||
Patch106: coreutils-9.3-cp--p-should-copy-NFSv4-acls.patch
|
||||
|
||||
# (sb) lin18nux/lsb compliance - multibyte functionality patch
|
||||
Patch800: coreutils-i18n.patch
|
||||
|
||||
|
|
@ -258,6 +262,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir
|
|||
%license COPYING
|
||||
|
||||
%changelog
|
||||
* Mon Sep 11 2023 Lukáš Zaoral <lzaoral@redhat.com> - 9.3-4
|
||||
- fix cp -p not copying NFSv4 acls (rhbz#2160675)
|
||||
|
||||
* Thu Aug 31 2023 Lukáš Zaoral <lzaoral@redhat.com> - 9.3-3
|
||||
- copy: reduce verbosity of -i and -u with --verbose (#2236321)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue