]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core/exec-credential: fix credentials plain dir exchanging
authorMike Yuan <me@yhndnzj.com>
Tue, 16 Dec 2025 01:10:32 +0000 (02:10 +0100)
committerMike Yuan <me@yhndnzj.com>
Tue, 16 Dec 2025 20:25:51 +0000 (21:25 +0100)
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

index d4ab704eb4b03a857bc495691c23afd5b224dae6..3d7f066400be3b750c5d152fb4e79d8b2f4ee027 100644 (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));
         }