fix infinite loop in recursive cp (introduced by 7.1, upstream)
This commit is contained in:
		
							parent
							
								
									a359684b15
								
							
						
					
					
						commit
						c39fe6a1cc
					
				
							
								
								
									
										154
									
								
								coreutils-7.1-cp-recursiveinfloop.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								coreutils-7.1-cp-recursiveinfloop.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,154 @@ | ||||
| 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 | ||||
|  #' | ||||
|   | ||||
| @ -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 @@ Source203:  coreutils-runuser-l.pamd | ||||
| 
 | ||||
| # 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 @@ the old GNU fileutils, sh-utils, and textutils packages. | ||||
| 
 | ||||
| # From upstream | ||||
| %patch1 -p1 -b .endfield | ||||
| %patch2 -p1 -b .recinfloop | ||||
| 
 | ||||
| # Our patches | ||||
| %patch100 -p1 -b .configure | ||||
| @ -311,6 +313,10 @@ fi | ||||
| /sbin/runuser | ||||
| 
 | ||||
| %changelog | ||||
| * Fri Feb 27 2009 Ondrej Vasik <ovasik@redhat.com> 7.1-5 | ||||
| - fix infinite loop in recursive cp (upstream, introduced | ||||
|   by 7.1) | ||||
| 
 | ||||
| * Thu Feb 26 2009 Ondrej Vasik <ovasik@redhat.com> 7.1-4 | ||||
| - fix showing ACL's for ls -Z (#487374), fix automatic | ||||
|   column width for it as well | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user