bug-coreutils
[Top][All Lists]
Advanced

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

Avoid misbehavior of a cross-device "mv" or "install".


From: Jim Meyering
Subject: Avoid misbehavior of a cross-device "mv" or "install".
Date: Thu, 15 Nov 2007 13:06:19 +0100

I noticed that mv and install might be coerced into dereferencing
a destination symlink.  Patch below.

As with almost any patch that eliminates a race condition, automating
a test would be tricky.  I tested manually by creating a dangling
destination symlink just before the first open in copy_reg.

        Avoid misbehavior of a cross-device "mv" or "install".
        Those programs must not dereference a destination symlink.
        * src/copy.c (copy_reg): Don't treat a dangling destination symlink
        differently in move mode.  In move mode, the only way the added
        O_EXCL can cause failure is when some other process has recreated
        the file this code unlinked a few instructions before.

---
 ChangeLog  |    9 +++++++++
 src/copy.c |    5 +++--
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 308a4a5..4ba2389 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2007-11-15  Jim Meyering  <address@hidden>
+
+       Avoid misbehavior of a cross-device "mv" or "install".
+       Those programs must not dereference a destination symlink.
+       * src/copy.c (copy_reg): Don't treat a dangling destination symlink
+       differently in move mode.  In move mode, the only way the added
+       O_EXCL can cause failure is when some other process has recreated
+       the file this code unlinked a few instructions before.
+
 2007-11-14  Jim Meyering  <address@hidden>

        Another bootstrap kludge.
diff --git a/src/copy.c b/src/copy.c
index e1cd5fa..1a265e3 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -371,8 +371,9 @@ copy_reg (char const *src_name, char const *dst_name,
         the above open fails with EEXIST.  If that happens, and
         lstat'ing the DST_NAME shows that it is a symlink, repeat
         the open call, but this time with the name of the final,
-        missing directory entry.  */
-      if (dest_desc < 0 && dest_errno == EEXIST)
+        missing directory entry.  All of this is relevant only for
+        cp, i.e., not in move_mode. */
+      if (dest_desc < 0 && dest_errno == EEXIST && ! x->move_mode)
        {
          struct stat dangling_link_sb;
          if (lstat (dst_name, &dangling_link_sb) == 0
--
1.5.3.5.666.gfb5f




reply via email to

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