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