Compare commits

...
Sign in to create a new pull request.

2 commits

3 changed files with 306 additions and 21 deletions

View file

@ -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, &copy_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

View file

@ -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
@ -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
@ -261,6 +264,10 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir
%license COPYING
%changelog
* Thu May 04 2023 Pádraig Brady <P@draigBrady.com> - 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 <releng@fedoraproject.org>
- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild

View file

@ -1,36 +1,60 @@
commit 7347caeb9d902d3fca2c11f69a55a3e578d93bfe
Author: Paul Eggert <eggert@cs.ucla.edu>
Date: Wed Apr 20 19:34:57 2022 -0700
backupfile: fix bug when renaming simple backups
* lib/backupfile.c (backupfile_internal): Fix bug when RENAME
and when doing simple backups. Problem reported by Steve Ward in:
https://bugs.gnu.org/55029
diff --git a/lib/backupfile.c b/lib/backupfile.c
index 1e9290a187..d9f465a3e0 100644
--- a/lib/backupfile.c
+++ b/lib/backupfile.c
@@ -332,7 +332,7 @@ backupfile_internal (int dir_fd, char const *file,
diff -Naur coreutils-9.1.orig/lib/backupfile.c coreutils-9.1/lib/backupfile.c
--- coreutils-9.1.orig/lib/backupfile.c 2022-04-08 11:22:26.000000000 +0000
+++ coreutils-9.1/lib/backupfile.c 2023-05-04 17:07:20.784911071 +0000
@@ -332,7 +332,7 @@
return s;
DIR *dirp = NULL;
- int sdir = AT_FDCWD;
+ int sdir = dir_fd;
+ int sdir = -1;
idx_t base_max = 0;
while (true)
{
@@ -371,10 +371,9 @@ backupfile_internal (int dir_fd, char const *file,
@@ -371,10 +371,10 @@
if (! rename)
break;
- int olddirfd = sdir < 0 ? dir_fd : sdir;
- idx_t offset = sdir < 0 ? 0 : base_offset;
+ idx_t offset = backup_type == simple_backups ? 0 : base_offset;
+ dir_fd = sdir < 0 ? dir_fd : sdir;
idx_t offset = sdir < 0 ? 0 : base_offset;
unsigned flags = backup_type == simple_backups ? 0 : RENAME_NOREPLACE;
- if (renameatu (olddirfd, file + offset, sdir, s + offset, flags) == 0)
+ if (renameatu (sdir, file + offset, sdir, s + offset, flags) == 0)
+ if (renameatu (dir_fd, file + offset, dir_fd, s + offset, flags) == 0)
break;
int e = errno;
if (! (e == EEXIST && extended))
diff -Naur coreutils-9.1.orig/tests/cp/backup-dir.sh coreutils-9.1/tests/cp/backup-dir.sh
--- coreutils-9.1.orig/tests/cp/backup-dir.sh 2022-04-08 11:22:18.000000000 +0000
+++ coreutils-9.1/tests/cp/backup-dir.sh 2023-05-04 17:07:24.851960384 +0000
@@ -1,5 +1,5 @@
#!/bin/sh
-# Ensure that cp -b doesn't back up directories.
+# Ensure that cp -b handles directories appropriately
# Copyright (C) 2006-2022 Free Software Foundation, Inc.
@@ -29,4 +29,10 @@
test -d y/x || fail=1
test -d y/x~ && fail=1
+# Bug 62607.
+# This would fail to backup using rename, and thus fail to replace the file
+mkdir -p src/foo dst/foo || framework_failure_
+touch src/foo/bar dst/foo/bar || framework_failure_
+cp --recursive --backup src/* dst || fail=1
+
Exit $fail
diff -Naur coreutils-9.1.orig/tests/mv/backup-dir.sh coreutils-9.1/tests/mv/backup-dir.sh
--- coreutils-9.1.orig/tests/mv/backup-dir.sh 2022-04-08 11:22:18.000000000 +0000
+++ coreutils-9.1/tests/mv/backup-dir.sh 2023-05-04 17:03:29.593098230 +0000
@@ -36,4 +36,10 @@
mv -T --backup=numbered C E/ || fail=1
mv -T --backup=numbered D E/ || fail=1
+# Bug#55029
+mkdir F && echo 1 >1 && echo 2 >2 && cp 1 F/X && cp 2 X || framework_failure_
+mv --backup=simple X F/ || fail=1
+compare 1 F/X~ || fail=1
+compare 2 F/X || fail=1
+
Exit $fail