From unknown Tue Jun 17 20:13:59 2025 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Mailer: MIME-tools 5.509 (Entity 5.509) Content-Type: text/plain; charset=utf-8 From: bug#52006 <52006@debbugs.gnu.org> To: bug#52006 <52006@debbugs.gnu.org> Subject: Status: [INSTALLED] cp: fix --preserve=ownership permissions bug Reply-To: bug#52006 <52006@debbugs.gnu.org> Date: Wed, 18 Jun 2025 03:13:59 +0000 retitle 52006 [INSTALLED] cp: fix --preserve=3Downership permissions bug reassign 52006 coreutils submitter 52006 Paul Eggert severity 52006 normal thanks From debbugs-submit-bounces@debbugs.gnu.org Sat Nov 20 16:51:29 2021 Received: (at submit) by debbugs.gnu.org; 20 Nov 2021 21:51:29 +0000 Received: from localhost ([127.0.0.1]:43776 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1moYGe-0000uF-SN for submit@debbugs.gnu.org; Sat, 20 Nov 2021 16:51:29 -0500 Received: from lists.gnu.org ([209.51.188.17]:55840) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1moYGd-0000u1-2l for submit@debbugs.gnu.org; Sat, 20 Nov 2021 16:51:28 -0500 Received: from eggs.gnu.org ([209.51.188.92]:37220) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1moYGc-0007L4-PW for bug-coreutils@gnu.org; Sat, 20 Nov 2021 16:51:26 -0500 Received: from zimbra.cs.ucla.edu ([131.179.128.68]:45078) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1moYGZ-00048t-R4 for bug-coreutils@gnu.org; Sat, 20 Nov 2021 16:51:26 -0500 Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 287BA160119 for ; Sat, 20 Nov 2021 13:51:20 -0800 (PST) Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id YaU9XjVFhxVS; Sat, 20 Nov 2021 13:51:18 -0800 (PST) Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id E58E516010D; Sat, 20 Nov 2021 13:51:18 -0800 (PST) X-Virus-Scanned: amavisd-new at zimbra.cs.ucla.edu Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id YQ-IkaNztkYt; Sat, 20 Nov 2021 13:51:18 -0800 (PST) Received: from penguin.cs.ucla.edu (Penguin.CS.UCLA.EDU [131.179.64.200]) by zimbra.cs.ucla.edu (Postfix) with ESMTPSA id BA4BE16010B; Sat, 20 Nov 2021 13:51:18 -0800 (PST) From: Paul Eggert To: bug-coreutils@gnu.org Subject: [INSTALLED] cp: fix --preserve=ownership permissions bug Date: Sat, 20 Nov 2021 13:51:13 -0800 Message-Id: <20211120215113.383277-1-eggert@cs.ucla.edu> X-Mailer: git-send-email 2.33.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Received-SPF: pass client-ip=131.179.128.68; envelope-from=eggert@cs.ucla.edu; helo=zimbra.cs.ucla.edu X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Spam-Score: -1.3 (-) X-Debbugs-Envelope-To: submit Cc: Paul Eggert X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -2.3 (--) This fixes a bug that I introduced in 2006-12-06T19:44:08Z!eggert@cs.ucla.edu. * src/copy.c (USE_XATTR): New macro. (copy_reg): Use it to help the compiler. Prefer open u+w to a later chmod u=3Drw; u+r isn=E2=80=99t needed for xattr. For the later u-= r, do only one (or zero) chmod calls instead of two (or one). In the last chmod, respect the umask instead of ignoring it. * tests/cp/preserve-mode.sh: Test for the bug. --- NEWS | 4 +++ src/copy.c | 54 ++++++++++++++++++++++----------------- tests/cp/preserve-mode.sh | 10 +++++++- 3 files changed, 44 insertions(+), 24 deletions(-) diff --git a/NEWS b/NEWS index 6350abc3c..3f7ed7218 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,10 @@ GNU coreutils NEWS = -*- outline -*- before adjusting it to the correct value. [bug introduced in coreutils-8.17] =20 + 'cp --preserve=3Downership A B' no longer ignores the umask when creat= ing B. + Also, 'cp --preserve-xattr A B' is less likely to temporarily chmod u+= w B. + [bug introduced in coreutils-6.7] + On macOS, 'cp A B' no longer miscopies when A is in an APFS file syste= m and B is in some other file system. [bug introduced in coreutils-9.0] diff --git a/src/copy.c b/src/copy.c index ba46cd3b7..9f20a34b9 100644 --- a/src/copy.c +++ b/src/copy.c @@ -66,6 +66,10 @@ #include "xstrtol.h" #include "selinux.h" =20 +#ifndef USE_XATTR +# define USE_XATTR false +#endif + #if USE_XATTR # include # include @@ -1138,11 +1142,13 @@ copy_reg (char const *src_name, char const *dst_n= ame, int dest_errno; int source_desc; mode_t src_mode =3D src_sb->st_mode; + mode_t extra_permissions; struct stat sb; struct stat src_open_sb; union scan_inference scan_inference; bool return_val =3D true; bool data_copy_required =3D x->data_copy_required; + bool preserve_xattr =3D USE_XATTR & x->preserve_xattr; =20 source_desc =3D open (src_name, (O_RDONLY | O_BINARY @@ -1239,9 +1245,16 @@ copy_reg (char const *src_name, char const *dst_na= me, =20 if (*new_dst) { + /* To allow copying xattrs on read-only files, create with u+w. + This satisfies an inode permission check done by + xattr_permission in fs/xattr.c of the GNU/Linux kernel. */ + mode_t open_mode =3D + ((dst_mode & ~omitted_permissions) + | (preserve_xattr && !x->owner_privileges ? S_IWUSR : 0)); + extra_permissions =3D open_mode & ~dst_mode; /* either 0 or S_IWUS= R */ + int open_flags =3D O_WRONLY | O_CREAT | O_BINARY; - dest_desc =3D open (dst_name, open_flags | O_EXCL, - dst_mode & ~omitted_permissions); + dest_desc =3D open (dst_name, open_flags | O_EXCL, open_mode); dest_errno =3D errno; =20 /* When trying to copy through a dangling destination symlink, @@ -1262,8 +1275,7 @@ copy_reg (char const *src_name, char const *dst_nam= e, { if (x->open_dangling_dest_symlink) { - dest_desc =3D open (dst_name, open_flags, - dst_mode & ~omitted_permissions); + dest_desc =3D open (dst_name, open_flags, open_mode); dest_errno =3D errno; } else @@ -1284,7 +1296,7 @@ copy_reg (char const *src_name, char const *dst_nam= e, } else { - omitted_permissions =3D 0; + omitted_permissions =3D extra_permissions =3D 0; } =20 if (dest_desc < 0) @@ -1302,6 +1314,14 @@ copy_reg (char const *src_name, char const *dst_na= me, goto close_src_and_dst_desc; } =20 + /* If extra permissions needed for copy_xattr didn't happen (e.g., + due to umask) chmod to add them temporarily; if that fails give + up with extra permissions, letting copy_attr fail later. */ + mode_t temporary_mode =3D sb.st_mode | extra_permissions; + if (temporary_mode !=3D sb.st_mode + && fchmod_or_lchmod (dest_desc, dst_name, temporary_mode) !=3D 0) + extra_permissions =3D 0; + /* --attributes-only overrides --reflink. */ if (data_copy_required && x->reflink_mode) { @@ -1433,25 +1453,11 @@ copy_reg (char const *src_name, char const *dst_n= ame, } } =20 - /* To allow copying xattrs on read-only files, temporarily chmod u+rw. - This workaround is required as an inode permission check is done - by xattr_permission() in fs/xattr.c of the GNU/Linux kernel tree. = */ - if (x->preserve_xattr) + if (preserve_xattr) { - bool access_changed =3D false; - - if (!(sb.st_mode & S_IWUSR) && geteuid () !=3D ROOT_UID) - { - access_changed =3D fchmod_or_lchmod (dest_desc, dst_name, - S_IRUSR | S_IWUSR) =3D=3D 0= ; - } - if (!copy_attr (src_name, source_desc, dst_name, dest_desc, x) && x->require_preserve_xattr) return_val =3D false; - - if (access_changed) - fchmod_or_lchmod (dest_desc, dst_name, dst_mode & ~omitted_permi= ssions); } =20 set_author (dst_name, dest_desc, src_sb); @@ -1472,11 +1478,13 @@ copy_reg (char const *src_name, char const *dst_n= ame, if (set_acl (dst_name, dest_desc, MODE_RW_UGO & ~cached_umask ()) = !=3D 0) return_val =3D false; } - else if (omitted_permissions) + else if (omitted_permissions | extra_permissions) { omitted_permissions &=3D ~ cached_umask (); - if (omitted_permissions - && fchmod_or_lchmod (dest_desc, dst_name, dst_mode) !=3D 0) + if ((omitted_permissions | extra_permissions) + && (fchmod_or_lchmod (dest_desc, dst_name, + dst_mode & ~ cached_umask ()) + !=3D 0)) { error (0, errno, _("preserving permissions for %s"), quoteaf (dst_name)); diff --git a/tests/cp/preserve-mode.sh b/tests/cp/preserve-mode.sh index c47dee650..c764300b6 100755 --- a/tests/cp/preserve-mode.sh +++ b/tests/cp/preserve-mode.sh @@ -1,5 +1,5 @@ #!/bin/sh -# ensure that cp's --no-preserve=3Dmode works correctly +# Check whether cp generates files with correct modes. =20 # Copyright (C) 2002-2021 Free Software Foundation, Inc. =20 @@ -55,4 +55,12 @@ if mkfifo fifo; then test "$(get_mode fifo)" =3D "$(get_mode fifo_copy)" || fail=3D1 fi =20 +# Test that plain --preserve=3Downership does not affect destination mod= e. +rm -f a b c || framework_failure_ +touch a || framework_failure_ +chmod 660 a || framework_failure_ +cp a b || fail=3D1 +cp --preserve=3Downership a c || fail=3D1 +test "$(get_mode b)" =3D "$(get_mode c)" || fail=3D1 + Exit $fail --=20 2.33.1 From debbugs-submit-bounces@debbugs.gnu.org Sat Nov 20 16:54:48 2021 Received: (at control) by debbugs.gnu.org; 20 Nov 2021 21:54:49 +0000 Received: from localhost ([127.0.0.1]:43781 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1moYJs-00014i-Ok for submit@debbugs.gnu.org; Sat, 20 Nov 2021 16:54:48 -0500 Received: from zimbra.cs.ucla.edu ([131.179.128.68]:42982) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1moYJo-00014R-Ua for control@debbugs.gnu.org; Sat, 20 Nov 2021 16:54:46 -0500 Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 6603D16010B for ; Sat, 20 Nov 2021 13:54:39 -0800 (PST) Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id okcGhoo5Scrm for ; Sat, 20 Nov 2021 13:54:38 -0800 (PST) Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id BEF7B160112 for ; Sat, 20 Nov 2021 13:54:38 -0800 (PST) X-Virus-Scanned: amavisd-new at zimbra.cs.ucla.edu Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id pIMHFficEx2o for ; Sat, 20 Nov 2021 13:54:38 -0800 (PST) Received: from [192.168.1.9] (cpe-172-91-119-151.socal.res.rr.com [172.91.119.151]) by zimbra.cs.ucla.edu (Postfix) with ESMTPSA id 9FDB316010D for ; Sat, 20 Nov 2021 13:54:38 -0800 (PST) Message-ID: <790a1104-a810-d490-ddce-38ddc6c8ff0f@cs.ucla.edu> Date: Sat, 20 Nov 2021 13:54:38 -0800 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.3.1 Content-Language: en-US To: control@debbugs.gnu.org From: Paul Eggert Subject: 52006 is done Organization: UCLA Computer Science Department Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: control X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) close 52006 From unknown Tue Jun 17 20:13:59 2025 Received: (at fakecontrol) by fakecontrolmessage; To: internal_control@debbugs.gnu.org From: Debbugs Internal Request Subject: Internal Control Message-Id: bug archived. Date: Sun, 19 Dec 2021 12:24:05 +0000 User-Agent: Fakemail v42.6.9 # This is a fake control message. # # The action: # bug archived. thanks # This fakemail brought to you by your local debbugs # administrator