From c8a534c05b41ef1f811153bff514ba945b99789f Mon Sep 17 00:00:00 2001 From: Ondřej Vašík Date: Jan 13 2016 11:51:29 +0000 Subject: mv: prevent dataloss when source dir is specified multiple times (#1297464, by P.Brady) --- diff --git a/coreutils-8.24-mv-duplicate-sources.patch b/coreutils-8.24-mv-duplicate-sources.patch new file mode 100644 index 0000000..f518cc6 --- /dev/null +++ b/coreutils-8.24-mv-duplicate-sources.patch @@ -0,0 +1,119 @@ +@@ -, +, @@ + destination + mv dir dir dir +--- + src/copy.c | 12 +++++++---- + tests/local.mk | 1 - + tests/mv/dup-source.sh | 46 +++++++++++++++++++++++++++++++++---------- + 3 files changed, 44 insertions(+), 15 deletions(-) +--- a/src/copy.c ++++ a/src/copy.c +@@ -2278,10 +2278,14 @@ copy_internal (char const *src_name, char const *dst_name, + error (0, 0, _("warning: source directory %s " + "specified more than once"), + quote (top_level_src_name)); +- /* We only do backups in move mode and for non dirs, +- and in move mode this won't be the issue as the source will +- be missing for subsequent attempts. +- There we just warn and return here. */ ++ /* In move mode, if a previous rename succeeded, then ++ we won't be in this path as the source is missing. If the ++ rename previously failed, then that has been handled. ++ Pretend this instance succeeded so the source isn't removed. */ ++ if (x->move_mode && rename_succeeded) ++ *rename_succeeded = true; ++ /* We only do backups in move mode, and for non directories. ++ So just ignore this repeated entry. */ + return true; + } + else if (x->dereference == DEREF_ALWAYS +--- a/tests/local.mk ++++ a/tests/local.mk +@@ -443,7 +443,6 @@ all_tests = \ + tests/cp/dir-rm-dest.sh \ + tests/cp/dir-slash.sh \ + tests/cp/dir-vs-file.sh \ +- tests/cp/duplicate-sources.sh \ + tests/cp/existing-perm-dir.sh \ + tests/cp/existing-perm-race.sh \ + tests/cp/fail-perm.sh \ +--- a/tests/mv/dup-source.sh ++++ a/tests/mv/dup-source.sh +@@ -24,25 +24,37 @@ print_ver_ cp mv + + skip_if_root_ + ++reset_files() { rm -fr a b d; touch a; mkdir b d; } ++ + for i in cp; do + + # cp may not fail in this case. +- +- rm -fr a d; touch a; mkdir d ++ reset_files + $i a a d/ 2> out || fail=1 +- rm -fr a d; touch a; mkdir d ++ reset_files + $i ./a a d/ 2>> out || fail=1 + ++ # Similarly for directories, but handle ++ # source == dest appropriately. ++ reset_files ++ $i -a ./b b d/ 2>> out || fail=1 ++ reset_files ++ returns_ 1 $i -a ./b b b/ 2>> out || fail=1 ++ + # cp succeeds with --backup=numbered. +- rm -fr a d; touch a; mkdir d ++ reset_files + $i --backup=numbered a a d/ 2>> out || fail=1 + + # But not with plain '--backup' +- rm -fr a d; touch a; mkdir d +- $i --backup a a d/ 2>> out && fail=1 ++ reset_files ++ returns_ 1 $i --backup a a d/ 2>> out || fail=1 ++ + cat < exp + $i: warning: source file 'a' specified more than once + $i: warning: source file 'a' specified more than once ++$i: warning: source directory 'b' specified more than once ++$i: cannot copy a directory, './b', into itself, 'b/b' ++$i: warning: source directory 'b' specified more than once + $i: will not overwrite just-created 'd/a' with 'a' + EOF + compare exp out || fail=1 +@@ -50,14 +62,28 @@ done + + for i in mv; do + # But mv *does* fail in this case (it has to). ++ reset_files ++ returns_ 1 $i a a d/ 2> out || fail=1 ++ returns_ 1 test -e a || fail=1 ++ reset_files ++ returns_ 1 $i ./a a d/ 2>> out || fail=1 ++ returns_ 1 test -e a || fail=1 ++ ++ # Similarly for directories, also handling ++ # source == dest appropriately. ++ reset_files ++ returns_ 1 $i ./b b d/ 2>> out || fail=1 ++ returns_ 1 test -e b || fail=1 ++ reset_files ++ returns_ 1 $i --verbose ./b b b/ 2>> out || fail=1 ++ test -d b || fail=1 + +- rm -fr a d; touch a; mkdir d +- $i a a d/ 2> out && fail=1 +- rm -fr a d; touch a; mkdir d +- $i ./a a d/ 2>> out && fail=1 + cat < exp + $i: cannot stat 'a': No such file or directory + $i: cannot stat 'a': No such file or directory ++$i: cannot stat 'b': No such file or directory ++$i: cannot move './b' to a subdirectory of itself, 'b/b' ++$i: warning: source directory 'b' specified more than once + EOF + compare exp out || fail=1 + done +-- diff --git a/coreutils.spec b/coreutils.spec index c4e1341..2a8e9f4 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.24 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -14,6 +14,8 @@ Source105: coreutils-colorls.sh Source106: coreutils-colorls.csh # From upstream +#mv: prevent dataloss when source directory is specified multiple t imes +Patch1: coreutils-8.24-mv-duplicate-sources.patch # Our patches #general patch to workaround koji build system issues @@ -38,6 +40,8 @@ Patch713: coreutils-4.5.3-langinfo.patch # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch +# (sb) lin18nux/lsb compliance - expand/unexpand +Patch801: coreutils-i18n-expand-unexpand.patch #getgrouplist() patch from Ulrich Drepper. Patch908: coreutils-getgrouplist.patch @@ -139,11 +143,13 @@ the old GNU fileutils, sh-utils, and textutils packages. # li18nux/lsb %patch800 -p1 -b .i18n +%patch801 -p1 -b .i18n-expand # Coreutils %patch908 -p1 -b .getgrouplist %patch912 -p1 -b .overflow %patch913 -p1 -b .testoff +%patch1 -p1 -b .dupl #SELinux %patch950 -p1 -b .selinux @@ -373,6 +379,13 @@ fi %{_sbindir}/chroot %changelog +* Wed Jan 13 2016 Ondrej Vasik - 8.24-3 +- mv: prevent dataloss when source dir is specified multiple + times (#1297464, by P.Brady) +- fix memory leak in sort/I18N (patches written by Pádraig, #1259942) +- Use the new i18n implementation for expand/unexpand +- fix one still existing occurance of non-full path in colorls.sh + * Thu Jul 16 2015 Ondrej Vasik 8.24-2 - use newer version of sort/I18N fix for CVE-2015-4041 and CVE-2015-4042