git: 0e0df1fc6753 - main - cp: Fix improper use of O_PATH.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 23 Jun 2025 20:39:00 UTC
The branch main has been updated by des:
URL: https://cgit.FreeBSD.org/src/commit/?id=0e0df1fc6753567c0ba1dd81859073b5d59a5a33
commit 0e0df1fc6753567c0ba1dd81859073b5d59a5a33
Author: Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2025-06-23 20:38:34 +0000
Commit: Dag-Erling Smørgrav <des@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);
}