From: Mike Yuan Date: Tue, 16 Dec 2025 01:10:32 +0000 (+0100) Subject: core/exec-credential: fix credentials plain dir exchanging X-Git-Tag: v259~10^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6c1bcdd614438b2068f62c4bab38ad3215b9dfe5;p=thirdparty%2Fsystemd.git core/exec-credential: fix credentials plain dir exchanging Follow-up for d796c6b7c64bd47b192c5351c955e9b8f4298bd4 rename() may yield ENOTEMPTY rather than EEXIST for existing dir, so catch that too. Also, both the source and target must be writable when exchanging. Test coverage for this logic (i.e. user units with ExecStartPre=) will be added later. --- diff --git a/src/core/exec-credential.c b/src/core/exec-credential.c index d4ab704eb4b..3d7f066400b 100644 --- a/src/core/exec-credential.c +++ b/src/core/exec-credential.c @@ -980,7 +980,13 @@ static int setup_credentials_plain_dir( r = RET_NERRNO(rename(workspace, cred_dir)); if (r >= 0) workspace_rm = NULL; - if (r == -EEXIST) { + if (IN_SET(r, -ENOTEMPTY, -EEXIST)) { + _cleanup_close_ int old_dfd = open(cred_dir, O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW); + if (old_dfd < 0) + return log_debug_errno(errno, "Failed to open credentials dir '%s': %m", cred_dir); + + (void) fd_acl_make_writable(old_dfd); + log_debug_errno(r, "Credential dir '%s' already populated, exchanging with workspace.", cred_dir); r = RET_NERRNO(renameat2(AT_FDCWD, workspace, AT_FDCWD, cred_dir, RENAME_EXCHANGE)); }