rpms/coreutils/devel coreutils-7.1-cp-recursiveinfloop.patch, NONE, 1.1 coreutils.spec, 1.250, 1.251

Ondrej Vasik ovasik at fedoraproject.org
Fri Feb 27 12:14:24 UTC 2009


Author: ovasik

Update of /cvs/extras/rpms/coreutils/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv26797

Modified Files:
	coreutils.spec 
Added Files:
	coreutils-7.1-cp-recursiveinfloop.patch 
Log Message:
fix infinite loop in recursive cp (introduced by 7.1, upstream)

coreutils-7.1-cp-recursiveinfloop.patch:

--- NEW FILE coreutils-7.1-cp-recursiveinfloop.patch ---
diff -urNp coreutils-7.1-orig/src/copy.c coreutils-7.1/src/copy.c
--- coreutils-7.1-orig/src/copy.c	2009-02-27 12:07:29.000000000 +0100
+++ coreutils-7.1/src/copy.c	2009-02-27 12:14:29.000000000 +0100
@@ -104,6 +104,7 @@ static bool copy_internal (char const *s
 			   struct dir_list *ancestors,
 			   const struct cp_options *x,
 			   bool command_line_arg,
+			   bool *first_dir_created_per_command_line_arg,
 			   bool *copy_into_self,
 			   bool *rename_succeeded);
 static bool owner_failure_ok (struct cp_options const *x);
@@ -201,13 +202,16 @@ copy_attr_by_name (char const *src_path,
    DST_NAME_IN is a directory that was created previously in the
    recursion.   SRC_SB and ANCESTORS describe SRC_NAME_IN.
    Set *COPY_INTO_SELF if SRC_NAME_IN is a parent of
+   FIRST_DIR_CREATED_PER_COMMAND_LINE_ARG  FIXME
    (or the same as) DST_NAME_IN; otherwise, clear it.
    Return true if successful.  */
 
 static bool
 copy_dir (char const *src_name_in, char const *dst_name_in, bool new_dst,
 	  const struct stat *src_sb, struct dir_list *ancestors,
-	  const struct cp_options *x, bool *copy_into_self)
+	  const struct cp_options *x,
+	  bool *first_dir_created_per_command_line_arg,
+	  bool *copy_into_self)
 {
   char *name_space;
   char *namep;
@@ -237,12 +241,20 @@ copy_dir (char const *src_name_in, char 
 
       ok &= copy_internal (src_name, dst_name, new_dst, src_sb->st_dev,
 			   ancestors, &non_command_line_options, false,
+			   first_dir_created_per_command_line_arg,
 			   &local_copy_into_self, NULL);
       *copy_into_self |= local_copy_into_self;
 
       free (dst_name);
       free (src_name);
 
+      /* If we're copying into self, there's no point in continuing,
+        and in fact, that would even infloop, now that we record only
+        the first created directory per command line argument.  */
+      if (local_copy_into_self)
+       break;
+
+
       namep += strlen (namep) + 1;
     }
   free (name_space);
@@ -1125,6 +1137,7 @@ restore_default_fscreatecon_or_die (void
    not known.  ANCESTORS points to a linked, null terminated list of
    devices and inodes of parent directories of SRC_NAME.  COMMAND_LINE_ARG
    is true iff SRC_NAME was specified on the command line.
+   FIRST_DIR_CREATED_PER_COMMAND_LINE_ARG is both input and output.
    Set *COPY_INTO_SELF if SRC_NAME is a parent of (or the
    same as) DST_NAME; otherwise, clear it.
    Return true if successful.  */
@@ -1135,6 +1148,7 @@ copy_internal (char const *src_name, cha
 	       struct dir_list *ancestors,
 	       const struct cp_options *x,
 	       bool command_line_arg,
+	       bool *first_dir_created_per_command_line_arg,
 	       bool *copy_into_self,
 	       bool *rename_succeeded)
 {
@@ -1815,11 +1829,15 @@ copy_internal (char const *src_name, cha
 		}
 	    }
 
-	  /* Insert the created directory's inode and device
-             numbers into the search structure, so that we can
-             avoid copying it again.  */
-	  if (!x->hard_link)
-	    remember_copied (dst_name, dst_sb.st_ino, dst_sb.st_dev);
+         /* Record the created directory's inode and device numbers into
+            the search structure, so that we can avoid copying it again.
+            Do this only for the first directory that is created for each
+            source command line argument.  */
+         if (!*first_dir_created_per_command_line_arg)
+           {
+             remember_copied (dst_name, dst_sb.st_ino, dst_sb.st_dev);
+             *first_dir_created_per_command_line_arg = true;
+           }
 
 	  if (x->verbose)
 	    emit_verbose (src_name, dst_name, NULL);
@@ -1840,6 +1858,7 @@ copy_internal (char const *src_name, cha
 	     in a source directory would cause the containing destination
 	     directory not to have owner/perms set properly.  */
 	  delayed_ok = copy_dir (src_name, dst_name, new_dst, &src_sb, dir, x,
+				 first_dir_created_per_command_line_arg,
 				 copy_into_self);
 	}
     }
@@ -2187,8 +2206,11 @@ copy (char const *src_name, char const *
   top_level_src_name = src_name;
   top_level_dst_name = dst_name;
 
+  bool first_dir_created_per_command_line_arg = false;
   return copy_internal (src_name, dst_name, nonexistent_dst, 0, NULL,
-			options, true, copy_into_self, rename_succeeded);
+			options, true,
+			&first_dir_created_per_command_line_arg,
+			copy_into_self, rename_succeeded);
 }
 
 /* Set *X to the default options for a value of type struct cp_options.  */
diff -urNp coreutils-7.1-orig/tests/cp/into-self coreutils-7.1/tests/cp/into-self
--- coreutils-7.1-orig/tests/cp/into-self	2008-09-18 09:06:57.000000000 +0200
+++ coreutils-7.1/tests/cp/into-self	2009-02-27 12:16:21.000000000 +0100
@@ -1,7 +1,7 @@
 #!/bin/sh
 # Confirm that copying a directory into itself gets a proper diagnostic.
 
-# Copyright (C) 2001, 2002, 2004, 2006-2008 Free Software Foundation, Inc.
+# Copyright (C) 2001, 2002, 2004, 2006-2009 Free Software Foundation, Inc.
 
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -28,15 +28,32 @@ fi
 
 . $srcdir/test-lib.sh
 
-mkdir dir || framework_failure
+mkdir a dir || framework_failure
 
 fail=0
 
 # This command should exit nonzero.
 cp -R dir dir 2> out && fail=1
+echo 1 >> out
+
+# This should, too.  However, with coreutils-7.1 it would infloop.
+cp -rl dir dir 2>> out && fail=1
+echo 2 >> out
+
+cp -rl a dir dir 2>> out && fail=1
+echo 3 >> out
+cp -rl a dir dir 2>> out && fail=1
+echo 4 >> out
 
 cat > exp <<\EOF
 cp: cannot copy a directory, `dir', into itself, `dir/dir'
+1
+cp: cannot copy a directory, `dir', into itself, `dir/dir'
+2
+cp: cannot copy a directory, `dir', into itself, `dir/dir'
+3
+cp: cannot copy a directory, `dir', into itself, `dir/dir'
+4
 EOF
 #'
 


Index: coreutils.spec
===================================================================
RCS file: /cvs/extras/rpms/coreutils/devel/coreutils.spec,v
retrieving revision 1.250
retrieving revision 1.251
diff -u -r1.250 -r1.251
--- coreutils.spec	26 Feb 2009 13:44:18 -0000	1.250
+++ coreutils.spec	27 Feb 2009 12:13:54 -0000	1.251
@@ -1,7 +1,7 @@
 Summary: A set of basic GNU tools commonly used in shell scripts
 Name:    coreutils
 Version: 7.1
-Release: 4%{?dist}
+Release: 5%{?dist}
 License: GPLv3+
 Group:   System Environment/Base
 Url:     http://www.gnu.org/software/coreutils/
@@ -20,6 +20,7 @@
 
 # From upstream
 Patch1: coreutils-7.1-sort-endoffields.patch
+Patch2: coreutils-7.1-cp-recursiveinfloop.patch
 
 # Our patches
 Patch100: coreutils-6.10-configuration.patch
@@ -100,6 +101,7 @@
 
 # From upstream
 %patch1 -p1 -b .endfield
+%patch2 -p1 -b .recinfloop
 
 # Our patches
 %patch100 -p1 -b .configure
@@ -311,6 +313,10 @@
 /sbin/runuser
 
 %changelog
+* Fri Feb 27 2009 Ondrej Vasik <ovasik at redhat.com> 7.1-5
+- fix infinite loop in recursive cp (upstream, introduced
+  by 7.1)
+
 * Thu Feb 26 2009 Ondrej Vasik <ovasik at redhat.com> 7.1-4
 - fix showing ACL's for ls -Z (#487374), fix automatic
   column width for it as well




More information about the fedora-extras-commits mailing list