From bd75118c16d8bca235b61dbb99326c043278a791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= Date: Thu, 18 Aug 2016 13:54:48 +0100 Subject: [PATCH] cp: with --parents --no-preserve=mode don't copy dir perms * src/cp.c (make_dir_parents_private): Use default permissions for created directories when --no-preserve=mode is specified. * tests/cp/cp-parents.sh: Add a test case. * NEWS: Mention the fix. Fixes http://bugs.gnu.org/24251 --- NEWS | 4 ++++ src/cp.c | 3 ++- tests/cp/cp-parents.sh | 27 +++++++++++++++++++-------- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/NEWS b/NEWS index c0e0d37..34a969e 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,10 @@ GNU coreutils NEWS -*- outline -*- handling ACLs on Cygwin and Solaris platforms. [bug introduced in coreutils-8.24] + cp --parents --no-preserve=mode, no longer copies permissions from source + directories, instead using default permissions for created directories. + [bug introduced in coreutils-5.93] + chcon, chgrp, chmod, chown, du, and rm, or specifically utilities using the FTS interface, now diagnose failures returned by readdir(). [this bug was inherent in the use of fts: thus, for rm the bug was diff --git a/src/cp.c b/src/cp.c index 3b5b6cb..13dc1ea 100644 --- a/src/cp.c +++ b/src/cp.c @@ -476,7 +476,8 @@ make_dir_parents_private (char const *const_dir, size_t src_offset, (src_mode & ~S_IRWXUGO) != 0. However, common practice is to ask mkdir to copy all the CHMOD_MODE_BITS, letting mkdir decide what to do with S_ISUID | S_ISGID | S_ISVTX. */ - mkdir_mode = src_mode & CHMOD_MODE_BITS & ~omitted_permissions; + mkdir_mode = x->explicit_no_preserve_mode ? S_IRWXUGO : src_mode; + mkdir_mode &= CHMOD_MODE_BITS & ~omitted_permissions; if (mkdir (dir, mkdir_mode) != 0) { error (0, errno, _("cannot make directory %s"), diff --git a/tests/cp/cp-parents.sh b/tests/cp/cp-parents.sh index b0be883..3819e3d 100755 --- a/tests/cp/cp-parents.sh +++ b/tests/cp/cp-parents.sh @@ -1,6 +1,4 @@ #!/bin/sh -# cp -R --parents dir-specified-with-trailing-slash/ other-dir -# would get a failed assertion. # Copyright (C) 2000-2016 Free Software Foundation, Inc. @@ -25,14 +23,15 @@ working_umask_or_skip_ # Run the setgid check from the just-created directory. skip_if_setgid_ -mkdir foo bar || framework_failure_ -mkdir -p a/b/c d e g || framework_failure_ -ln -s d/a sym || framework_failure_ -touch f || framework_failure_ - +{ + mkdir foo bar + mkdir -p a/b/c d e g + ln -s d/a sym + touch f +} || framework_failure_ # With 4.0.37 and earlier (back to when?), this would fail -# with the failed assertion from dirname.c. +# with the failed assertion from dirname.c due to the trailing slash. cp -R --parents foo/ bar || fail=1 # Exercise the make_path and re_protect code in cp.c. @@ -55,4 +54,16 @@ p=$(ls -ld g/sym|cut -b-10); case $p in drwx-w--w-);; *) fail=1;; esac p=$(ls -ld e/d/a/b/c|cut -b-10); case $p in drwxr-xr-x);; *) fail=1;; esac p=$(ls -ld g/sym/b/c|cut -b-10); case $p in drwxr-xr-x);; *) fail=1;; esac +# Before 8.25 cp --parents --no-preserve=mode would copy +# the mode bits from the source directories +{ + mkdir -p np/b && + chmod 0700 np && + touch np/b/file && + chmod 775 np/b/file && + mkdir np_dest +} || framework_failure_ +cp --parents --no-preserve=mode np/b/file np_dest/ || fail=1 +p=$(ls -ld np_dest/np|cut -b-10); case $p in drwxr-xr-x);; *) fail=1;; esac + Exit $fail -- 2.5.5