core/exec-credential: fix credentials plain dir exchanging

Follow-up for d796c6b7c6

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.
This commit is contained in:
Mike Yuan
2025-12-16 21:25:51 +01:00
parent 5188da568c
commit 6c1bcdd614
+7 -1
View File
@@ -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));
}