From 6c1bcdd614438b2068f62c4bab38ad3215b9dfe5 Mon Sep 17 00:00:00 2001 From: Mike Yuan Date: Tue, 16 Dec 2025 02:10:32 +0100 Subject: [PATCH] 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. --- src/core/exec-credential.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/core/exec-credential.c b/src/core/exec-credential.c index d4ab704eb4..3d7f066400 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)); }