On 24/03/2024 16:42, Bruno Haible wrote:
The cp/preserve-mode test fails on Alpine Linux 3.18.test-suite.log from Alpine Linux 3.18: FAIL: tests/cp/preserve-mode ============================
+ mkdir d1 d2 + chmod 705 d2 + cp '--no-preserve=mode' -r d2 d3 + get_mode d1 + stat '-c%f' d1 + get_mode d3 + stat '-c%f' d3 + test 45ed '=' 41ed + fail=1
This is another setgid issue, and looks like a real bug. It was there since 8.20 (2012) it seems. cp is not maintaining the setgid bit, that mkdir(2) created. I can't repro on my Fedora system, but can on Alpine, where set_acl() falls back to a chmod because it can't set ACLs. The attached fixes this by including the setgid bit in the fallback mode if appropriate. cheers, Pádraig
From 30039cb23a2cbdc2ef92e7c474bd9d9ae404ffe0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= <p...@draigbrady.com> Date: Mon, 25 Mar 2024 22:17:35 +0000 Subject: [PATCH] cp: with --no-preserve=mode ensure set-group-ID bits maintained on dirs This issue was introduced in commit v8.19-145-g24ebca6 * src/copy.c (copy_internal): On systems that don't support ACLs, the fallback default chmod done on directories should maintain the set-group-ID, as that's generally auto-set by the system. * NEWS: Mention the fix. Reported by Bruno Haible on Alpine (with tests/cp/preserve-mode.sh) --- NEWS | 5 +++++ src/copy.c | 3 +++ 2 files changed, 8 insertions(+) diff --git a/NEWS b/NEWS index a6ec7c6ef..872723e4f 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,11 @@ GNU coreutils NEWS -*- outline -*- to preserve ownership" when copying to GNU/Linux CIFS file systems. They do this by working around some Linux CIFS bugs. + cp --no-preserve=mode will correctly maintain set-group-ID bits + for created directories. Previously on systems that didn't support ACLs, + cp would have reset the set-group-ID bit on created directories. + [bug introduced in coreutils-8.20] + join and uniq now support multi-byte characters better. For example, 'join -tX' now works even if X is a multi-byte character, and both programs now treat multi-byte characters like U+3000 diff --git a/src/copy.c b/src/copy.c index 0318e0067..d584a27eb 100644 --- a/src/copy.c +++ b/src/copy.c @@ -3268,6 +3268,9 @@ skip: { int default_permissions = S_ISDIR (src_mode) || S_ISSOCK (src_mode) ? S_IRWXUGO : MODE_RW_UGO; + dst_mode = dst_sb.st_mode; + if (S_ISDIR (src_mode)) /* Keep set-group-ID for directories. */ + default_permissions |= (dst_mode & S_ISGID); if (set_acl (dst_name, -1, default_permissions & ~cached_umask ()) != 0) return false; } -- 2.44.0