From 4e367ece4a9dccf89f859af217ed72e51425a4b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?=
Date: Thu, 4 May 2023 19:40:43 +0100 Subject: [PATCH 1/2] further fixes to backups; broken in 9.1 From https://bugs.gnu.org/55029 From https://bugs.gnu.org/62607 --- coreutils.spec | 5 ++- gnulib-simple-backup-fix.patch | 64 +++++++++++++++++++++++----------- 2 files changed, 48 insertions(+), 21 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 8c4a6b1..abe4c99 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.1 -Release: 11%{?dist} +Release: 12%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -261,6 +261,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Thu May 04 2023 Pádraig Brady
- 9.1-12
+- further fixes to backups; broken in 9.1
+
* Thu Jan 19 2023 Fedora Release Engineering
Date: Thu, 4 May 2023 22:14:24 +0100
Subject: [PATCH 2/2] fix some directory-relative syscalls; broken in 9.1
From https://bugs.gnu.org/55910
From https://bugs.gnu.org/63245
---
coreutils-9.1-copy-relative-dir.patch | 254 ++++++++++++++++++++++++++
coreutils.spec | 4 +
2 files changed, 258 insertions(+)
create mode 100644 coreutils-9.1-copy-relative-dir.patch
diff --git a/coreutils-9.1-copy-relative-dir.patch b/coreutils-9.1-copy-relative-dir.patch
new file mode 100644
index 0000000..a75d162
--- /dev/null
+++ b/coreutils-9.1-copy-relative-dir.patch
@@ -0,0 +1,254 @@
+diff -Naur coreutils-9.1.orig/src/copy.c coreutils-9.1/src/copy.c
+--- coreutils-9.1.orig/src/copy.c 2022-04-15 13:53:28.000000000 +0000
++++ coreutils-9.1/src/copy.c 2023-05-04 21:09:46.290253081 +0000
+@@ -1954,6 +1954,7 @@
+ bool restore_dst_mode = false;
+ char *earlier_file = NULL;
+ char *dst_backup = NULL;
++ char const *drelname = *dst_relname ? dst_relname : ".";
+ bool delayed_ok;
+ bool copied_as_regular = false;
+ bool dest_is_symlink = false;
+@@ -1971,7 +1972,7 @@
+ if (x->move_mode)
+ {
+ if (rename_errno < 0)
+- rename_errno = (renameatu (AT_FDCWD, src_name, dst_dirfd, dst_relname,
++ rename_errno = (renameatu (AT_FDCWD, src_name, dst_dirfd, drelname,
+ RENAME_NOREPLACE)
+ ? errno : 0);
+ nonexistent_dst = *rename_succeeded = new_dst = rename_errno == 0;
+@@ -1983,7 +1984,7 @@
+ {
+ char const *name = rename_errno == 0 ? dst_name : src_name;
+ int dirfd = rename_errno == 0 ? dst_dirfd : AT_FDCWD;
+- char const *relname = rename_errno == 0 ? dst_relname : src_name;
++ char const *relname = rename_errno == 0 ? drelname : src_name;
+ int fstatat_flags
+ = x->dereference == DEREF_NEVER ? AT_SYMLINK_NOFOLLOW : 0;
+ if (follow_fstatat (dirfd, relname, &src_sb, fstatat_flags) != 0)
+@@ -2051,8 +2052,7 @@
+ int fstatat_flags = use_lstat ? AT_SYMLINK_NOFOLLOW : 0;
+ if (!use_lstat && nonexistent_dst < 0)
+ new_dst = true;
+- else if (follow_fstatat (dst_dirfd, dst_relname, &dst_sb,
+- fstatat_flags)
++ else if (follow_fstatat (dst_dirfd, drelname, &dst_sb, fstatat_flags)
+ == 0)
+ {
+ have_dst_lstat = use_lstat;
+@@ -2077,7 +2077,7 @@
+ bool return_now = false;
+
+ if (x->interactive != I_ALWAYS_NO
+- && ! same_file_ok (src_name, &src_sb, dst_dirfd, dst_relname,
++ && ! same_file_ok (src_name, &src_sb, dst_dirfd, drelname,
+ &dst_sb, x, &return_now))
+ {
+ error (0, 0, _("%s and %s are the same file"),
+@@ -2140,7 +2140,7 @@
+ cp and mv treat -i and -f differently. */
+ if (x->move_mode)
+ {
+- if (abandon_move (x, dst_name, dst_dirfd, dst_relname, &dst_sb))
++ if (abandon_move (x, dst_name, dst_dirfd, drelname, &dst_sb))
+ {
+ /* Pretend the rename succeeded, so the caller (mv)
+ doesn't end up removing the source file. */
+@@ -2321,14 +2321,11 @@
+ Otherwise, use AT_SYMLINK_NOFOLLOW, in case dst_name is a symlink. */
+ if (have_dst_lstat)
+ dst_lstat_sb = &dst_sb;
++ else if (fstatat (dst_dirfd, drelname, &tmp_buf, AT_SYMLINK_NOFOLLOW)
++ == 0)
++ dst_lstat_sb = &tmp_buf;
+ else
+- {
+- if (fstatat (dst_dirfd, dst_relname, &tmp_buf,
+- AT_SYMLINK_NOFOLLOW) == 0)
+- dst_lstat_sb = &tmp_buf;
+- else
+- lstat_ok = false;
+- }
++ lstat_ok = false;
+
+ /* Never copy through a symlink we've just created. */
+ if (lstat_ok
+@@ -2475,8 +2472,7 @@
+ if (x->move_mode)
+ {
+ if (rename_errno == EEXIST)
+- rename_errno = ((renameat (AT_FDCWD, src_name, dst_dirfd, dst_relname)
+- == 0)
++ rename_errno = (renameat (AT_FDCWD, src_name, dst_dirfd, drelname) == 0
+ ? 0 : errno);
+
+ if (rename_errno == 0)
+@@ -2576,7 +2572,7 @@
+ or not, and this is enforced above. Therefore we check the src_mode
+ and operate on dst_name here as a tighter constraint and also because
+ src_mode is readily available here. */
+- if ((unlinkat (dst_dirfd, dst_relname,
++ if ((unlinkat (dst_dirfd, drelname,
+ S_ISDIR (src_mode) ? AT_REMOVEDIR : 0)
+ != 0)
+ && errno != ENOENT)
+@@ -2646,7 +2642,7 @@
+ to ask mkdir to copy all the CHMOD_MODE_BITS, letting mkdir
+ decide what to do with S_ISUID | S_ISGID | S_ISVTX. */
+ mode_t mode = dst_mode_bits & ~omitted_permissions;
+- if (mkdirat (dst_dirfd, dst_relname, mode) != 0)
++ if (mkdirat (dst_dirfd, drelname, mode) != 0)
+ {
+ error (0, errno, _("cannot create directory %s"),
+ quoteaf (dst_name));
+@@ -2657,8 +2653,7 @@
+ for writing the directory's contents. Check if these
+ permissions are there. */
+
+- if (fstatat (dst_dirfd, dst_relname, &dst_sb,
+- AT_SYMLINK_NOFOLLOW) != 0)
++ if (fstatat (dst_dirfd, drelname, &dst_sb, AT_SYMLINK_NOFOLLOW) != 0)
+ {
+ error (0, errno, _("cannot stat %s"), quoteaf (dst_name));
+ goto un_backup;
+@@ -2670,7 +2665,7 @@
+ dst_mode = dst_sb.st_mode;
+ restore_dst_mode = true;
+
+- if (lchmodat (dst_dirfd, dst_relname, dst_mode | S_IRWXU) != 0)
++ if (lchmodat (dst_dirfd, drelname, dst_mode | S_IRWXU) != 0)
+ {
+ error (0, errno, _("setting permissions for %s"),
+ quoteaf (dst_name));
+@@ -2924,7 +2919,7 @@
+ /* Now that the destination file is very likely to exist,
+ add its info to the set. */
+ struct stat sb;
+- if (fstatat (dst_dirfd, dst_relname, &sb, AT_SYMLINK_NOFOLLOW) == 0)
++ if (fstatat (dst_dirfd, drelname, &sb, AT_SYMLINK_NOFOLLOW) == 0)
+ record_file (x->dest_info, dst_relname, &sb);
+ }
+
+@@ -2957,7 +2952,7 @@
+ timespec[1] = get_stat_mtime (&src_sb);
+
+ int utimensat_flags = dest_is_symlink ? AT_SYMLINK_NOFOLLOW : 0;
+- if (utimensat (dst_dirfd, dst_relname, timespec, utimensat_flags) != 0)
++ if (utimensat (dst_dirfd, drelname, timespec, utimensat_flags) != 0)
+ {
+ error (0, errno, _("preserving times for %s"), quoteaf (dst_name));
+ if (x->require_preserve)
+@@ -2969,7 +2964,7 @@
+ if (!dest_is_symlink && x->preserve_ownership
+ && (new_dst || !SAME_OWNER_AND_GROUP (src_sb, dst_sb)))
+ {
+- switch (set_owner (x, dst_name, dst_dirfd, dst_relname, -1,
++ switch (set_owner (x, dst_name, dst_dirfd, drelname, -1,
+ &src_sb, new_dst, &dst_sb))
+ {
+ case -1:
+@@ -3024,8 +3019,9 @@
+ the lstat, but deducing the current destination mode
+ is tricky in the presence of implementation-defined
+ rules for special mode bits. */
+- if (new_dst && fstatat (dst_dirfd, dst_relname, &dst_sb,
+- AT_SYMLINK_NOFOLLOW) != 0)
++ if (new_dst && (fstatat (dst_dirfd, drelname, &dst_sb,
++ AT_SYMLINK_NOFOLLOW)
++ != 0))
+ {
+ error (0, errno, _("cannot stat %s"), quoteaf (dst_name));
+ return false;
+@@ -3038,7 +3034,7 @@
+
+ if (restore_dst_mode)
+ {
+- if (lchmodat (dst_dirfd, dst_relname, dst_mode | omitted_permissions)
++ if (lchmodat (dst_dirfd, drelname, dst_mode | omitted_permissions)
+ != 0)
+ {
+ error (0, errno, _("preserving permissions for %s"),
+@@ -3068,7 +3064,7 @@
+ if (dst_backup)
+ {
+ char const *dst_relbackup = &dst_backup[dst_relname - dst_name];
+- if (renameat (dst_dirfd, dst_relbackup, dst_dirfd, dst_relname) != 0)
++ if (renameat (dst_dirfd, dst_relbackup, dst_dirfd, drelname) != 0)
+ error (0, errno, _("cannot un-backup %s"), quoteaf (dst_name));
+ else
+ {
+diff -Naur coreutils-9.1.orig/src/cp.c coreutils-9.1/src/cp.c
+--- coreutils-9.1.orig/src/cp.c 2023-05-04 21:08:46.747627135 +0000
++++ coreutils-9.1/src/cp.c 2023-05-04 21:09:50.067286480 +0000
+@@ -273,15 +273,19 @@
+ when done. */
+
+ static bool
+-re_protect (char const *const_dst_name, int dst_dirfd, char const *dst_relname,
++re_protect (char const *const_dst_name, int dst_dirfd, char const *dst_fullname,
+ struct dir_attr *attr_list, const struct cp_options *x)
+ {
+ struct dir_attr *p;
+ char *dst_name; /* A copy of CONST_DST_NAME we can change. */
+- char *src_name; /* The source name in 'dst_name'. */
++ char *src_name; /* The relative source name in 'dst_name'. */
++ char *full_src_name; /* The full source name in 'dst_name'. */
+
+ ASSIGN_STRDUPA (dst_name, const_dst_name);
+- src_name = dst_name + (dst_relname - const_dst_name);
++ full_src_name = dst_name + (dst_fullname - const_dst_name);
++ src_name = full_src_name;
++ while (*src_name == '/')
++ src_name++;
+
+ for (p = attr_list; p; p = p->next)
+ {
+@@ -324,7 +328,7 @@
+
+ if (x->preserve_mode)
+ {
+- if (copy_acl (src_name, -1, dst_name, -1, p->st.st_mode) != 0)
++ if (copy_acl (full_src_name, -1, dst_name, -1, p->st.st_mode) != 0)
+ return false;
+ }
+ else if (p->restore_mode)
+@@ -664,6 +668,7 @@
+ bool parent_exists = true; /* True if dir_name (dst_name) exists. */
+ struct dir_attr *attr_list;
+ char *arg_in_concat = NULL;
++ char *full_arg_in_concat = NULL;
+ char *arg = file[i];
+
+ /* Trailing slashes are meaningful (i.e., maybe worth preserving)
+@@ -696,6 +701,7 @@
+ (x->verbose ? "%s -> %s\n" : NULL),
+ &attr_list, &new_dst, x));
+
++ full_arg_in_concat = arg_in_concat;
+ while (*arg_in_concat == '/')
+ arg_in_concat++;
+ }
+@@ -724,7 +730,7 @@
+ new_dst, x, ©_into_self, NULL);
+
+ if (parents_option)
+- ok &= re_protect (dst_name, target_dirfd, arg_in_concat,
++ ok &= re_protect (dst_name, target_dirfd, full_arg_in_concat,
+ attr_list, x);
+ }
+
+diff -Naur coreutils-9.1.orig/tests/cp/cp-parents.sh coreutils-9.1/tests/cp/cp-parents.sh
+--- coreutils-9.1.orig/tests/cp/cp-parents.sh 2022-04-08 11:22:18.000000000 +0000
++++ coreutils-9.1/tests/cp/cp-parents.sh 2023-05-04 21:09:50.067286480 +0000
+@@ -66,4 +66,10 @@
+ cp --parents --no-preserve=mode np/b/file np_dest/ || fail=1
+ p=$(ls -ld np_dest/np|cut -b-10); case $p in drwxr-xr-x);; *) fail=1;; esac
+
++# coreutils 9.1-9.3 inclusive would fail to copy acls for absolute dirs
++mkdir dest || framework_failure_
++if test -f /bin/ls; then
++ cp -t dest --parents -p /bin/ls || fail=1
++fi
++
+ Exit $fail
diff --git a/coreutils.spec b/coreutils.spec
index abe4c99..85f43c7 100644
--- a/coreutils.spec
+++ b/coreutils.spec
@@ -23,6 +23,9 @@ Patch1: gnulib-simple-backup-fix.patch
# basic support for checking NFSv4 ACLs (#2137866)
Patch2: coreutils-nfsv4-acls.patch
+# Fix directory-relative syscalls in copy code; broken in 9.1
+Patch3: coreutils-9.1-copy-relative-dir.patch
+
# disable the test-lock gnulib test prone to deadlock
Patch100: coreutils-8.26-test-lock.patch
@@ -263,6 +266,7 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir
%changelog
* Thu May 04 2023 Pádraig Brady - 9.1-12
- further fixes to backups; broken in 9.1
+- fix some directory-relative syscalls; broken in 9.1
* Thu Jan 19 2023 Fedora Release Engineering