bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#31364: cp -rfs: Fails to overwrite a symlink when it is on a differe


From: Illia Bobyr
Subject: bug#31364: cp -rfs: Fails to overwrite a symlink when it is on a different device
Date: Fri, 04 May 2018 23:37:55 +0000

Hello,

I have found a bug in "cp -rfs".

Steps to reproduce:

1. Given "path1" and "path2" are on different devices.
2. $ touch "path1/file"
3. $ cd path2/; ln -s path1/file
4. $ cp --symbolic-link --force --recursive path1/file .

Expected:
The link is overwritten with an exact copy.

Actual result:
cp shows an error:
    cp: 'path1/file' and './file' are the same file

This bug was introduced in

http://git.savannah.gnu.org/cgit/coreutils.git/commit/?id=376967889ed7ed561e46ff6d88a66779db62737a

Specifically this hunk:

diff --git a/src/copy.c b/src/copy.c
index e3832c2..9dbd536 100644
--- a/src/copy.c
<http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/copy.c?id=2f69dba5df8caaf9eda658c1808b1379e9949f22>
+++ b/src/copy.c
<http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/copy.c?id=376967889ed7ed561e46ff6d88a66779db62737a>
@@ -46,6 +46,7 @@
#include "file-set.h"
#include "filemode.h"
#include "filenamecat.h"
+#include "force-link.h"
#include "full-write.h"
#include "hash.h"
#include "hash-triple.h"
@@ -1623,11 +1624,13 @@ same_file_ok (char const *src_name, struct stat
const *src_sb,
}
}
- /* It's ok to remove a destination symlink. But that works only when we
- unlink before opening the destination and when the source and destination
- files are on the same partition. */
- if (x->unlink_dest_before_opening
- && S_ISLNK (dst_sb_link->st_mode))
+ /* It's ok to remove a destination symlink. But that works only
+ when creating symbolic links, or when the source and destination
+ are on the same file system and when creating hard links or when
+ unlinking before opening the destination. */
+ if (x->symbolic_link
+ || ((x->hard_link || x->unlink_dest_before_opening)
+ && S_ISLNK (dst_sb_link->st_mode)))
return dst_sb_link->st_dev == src_sb_link->st_dev;
if (x->dereference == DEREF_NEVER)

Two patches that fix the issue are attached.
They are against the current master in
https://github.com/coreutils/coreutils
The changes are also here:

https://github.com/coreutils/coreutils/compare/master...ilya-bobyr:master

Thank you, Illia Bobyr

Attachment: 0002-cp-Overwrite-symlinks-on-another-device.patch
Description: Text Data

Attachment: 0001-cp-No-dup-check-for-unlink_dest_after_failed_open.patch
Description: Text Data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]