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 | Summary: A set of basic GNU tools commonly used in shell scripts | ||||||
| Name:    coreutils | Name:    coreutils | ||||||
| Version: 7.1 | Version: 7.1 | ||||||
| Release: 4%{?dist} | Release: 5%{?dist} | ||||||
| License: GPLv3+ | License: GPLv3+ | ||||||
| Group:   System Environment/Base | Group:   System Environment/Base | ||||||
| Url:     http://www.gnu.org/software/coreutils/ | Url:     http://www.gnu.org/software/coreutils/ | ||||||
| @ -20,6 +20,7 @@ Source203:  coreutils-runuser-l.pamd | |||||||
| 
 | 
 | ||||||
| # From upstream | # From upstream | ||||||
| Patch1: coreutils-7.1-sort-endoffields.patch | Patch1: coreutils-7.1-sort-endoffields.patch | ||||||
|  | Patch2: coreutils-7.1-cp-recursiveinfloop.patch | ||||||
| 
 | 
 | ||||||
| # Our patches | # Our patches | ||||||
| Patch100: coreutils-6.10-configuration.patch | Patch100: coreutils-6.10-configuration.patch | ||||||
| @ -100,6 +101,7 @@ the old GNU fileutils, sh-utils, and textutils packages. | |||||||
| 
 | 
 | ||||||
| # From upstream | # From upstream | ||||||
| %patch1 -p1 -b .endfield | %patch1 -p1 -b .endfield | ||||||
|  | %patch2 -p1 -b .recinfloop | ||||||
| 
 | 
 | ||||||
| # Our patches | # Our patches | ||||||
| %patch100 -p1 -b .configure | %patch100 -p1 -b .configure | ||||||
| @ -311,6 +313,10 @@ fi | |||||||
| /sbin/runuser | /sbin/runuser | ||||||
| 
 | 
 | ||||||
| %changelog | %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 | * Thu Feb 26 2009 Ondrej Vasik <ovasik@redhat.com> 7.1-4 | ||||||
| - fix showing ACL's for ls -Z (#487374), fix automatic | - fix showing ACL's for ls -Z (#487374), fix automatic | ||||||
|   column width for it as well |   column width for it as well | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user