The branch main has been updated by des:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=0e0df1fc6753567c0ba1dd81859073b5d59a5a33

commit 0e0df1fc6753567c0ba1dd81859073b5d59a5a33
Author:     Dag-Erling Smørgrav <d...@freebsd.org>
AuthorDate: 2025-06-23 20:38:34 +0000
Commit:     Dag-Erling Smørgrav <d...@freebsd.org>
CommitDate: 2025-06-23 20:38:50 +0000

    cp: Fix improper use of O_PATH.
    
    This does not appear to make any practical difference at the moment, but
    technically `O_PATH` means “I'm not going to use this descriptor for any
    other purposes than vnode lookups”, so using it to read the directory's
    ACLs is improper and might fail in the future.
    
    Fixes:          82fc0d09e8625
    Sponsored by:   Klara, Inc.
    Reviewed by:    kevans
    Differential Revision:  https://reviews.freebsd.org/D50984
---
 bin/cp/tests/cp_test.sh | 18 ++++++++++++++++++
 bin/cp/utils.c          |  2 +-
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/bin/cp/tests/cp_test.sh b/bin/cp/tests/cp_test.sh
index f06238c89367..d5268ed4c4c9 100755
--- a/bin/cp/tests/cp_test.sh
+++ b/bin/cp/tests/cp_test.sh
@@ -183,6 +183,7 @@ atf_test_case pflag_acls
 pflag_acls_body()
 {
        mkdir dir
+       ln -s dir lnk
        echo "hello" >dir/file
        if ! setfacl -m g:staff:D::allow dir ||
           ! setfacl -m g:staff:d::allow dir/file ; then
@@ -204,12 +205,21 @@ pflag_acls_body()
        atf_check cp -rp dir dst4
        atf_check -o match:"group:staff:-+D-+" getfacl dst4
        atf_check -o match:"group:staff:-+d-+" getfacl dst4/file
+       # source is a link without -p
+       atf_check cp -r lnk dst5
+       atf_check -o not-match:"group:staff:-+D-+" getfacl dst5
+       atf_check -o not-match:"group:staff:-+d-+" getfacl dst5/file
+       # source is a link with -p
+       atf_check cp -rp lnk dst6
+       atf_check -o match:"group:staff:-+D-+" getfacl dst6
+       atf_check -o match:"group:staff:-+d-+" getfacl dst6/file
 }
 
 atf_test_case pflag_flags
 pflag_flags_body()
 {
        mkdir dir
+       ln -s dir lnk
        echo "hello" >dir/file
        if ! chflags nodump dir ||
           ! chflags nodump dir/file ; then
@@ -231,6 +241,14 @@ pflag_flags_body()
        atf_check cp -rp dir dst4
        atf_check -o match:"nodump" stat -f%Sf dst4
        atf_check -o match:"nodump" stat -f%Sf dst4/file
+       # source is a link without -p
+       atf_check cp -r lnk dst5
+       atf_check -o not-match:"nodump" stat -f%Sf dst5
+       atf_check -o not-match:"nodump" stat -f%Sf dst5/file
+       # source is a link with -p
+       atf_check cp -rp lnk dst6
+       atf_check -o match:"nodump" stat -f%Sf dst6
+       atf_check -o match:"nodump" stat -f%Sf dst6/file
 }
 
 recursive_link_setup()
diff --git a/bin/cp/utils.c b/bin/cp/utils.c
index 3e669b4b513d..cfc0f0f12603 100644
--- a/bin/cp/utils.c
+++ b/bin/cp/utils.c
@@ -458,7 +458,7 @@ preserve_dir_acls(const char *source_dir, const char 
*dest_dir)
 {
        int source_fd = -1, dest_fd = -1, ret;
 
-       if ((source_fd = open(source_dir, O_PATH)) < 0) {
+       if ((source_fd = open(source_dir, O_DIRECTORY | O_RDONLY)) < 0) {
                warn("%s: failed to copy ACLs", source_dir);
                return (-1);
        }

Reply via email to