From 8dc5e5bc4d05a1368e3a147ce046b78a1fab1a5c Mon Sep 17 00:00:00 2001 From: Sam Brkopac Date: Tue, 22 Sep 2026 12:07:18 -0700 Subject: [PATCH] tmpfiles: only chmod/chown directories that differ from the rule makedir() returns 0 when the directory already exists, so the EEXIST branch never ran and existing directories never had their mode fixed. chown() on the other hand ran every time, which fails with EPERM on an immutable directory even when the owner is already correct: tmpfiles: Failed chown(/var/empty, 0, 0): Operation not permitted Stat the directory and only change the mode or owner if it differs. --- src/tmpfiles.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/tmpfiles.c b/src/tmpfiles.c index 4825ee6a..f166e078 100644 --- a/src/tmpfiles.c +++ b/src/tmpfiles.c @@ -558,10 +558,12 @@ static void tmpfiles(char *line) gid = 0; rc = makedir(path, mode ?: 0755); - if (rc && errno == EEXIST) - rc = chmod(path, mode ?: 0755); - if (chown(path, uid, gid)) - warn("Failed chown(%s, %d, %d)", path, uid, gid); + if (!rc && !(rc = stat(path, &st))) { + if ((st.st_mode & 07777) != (mode ?: 0755)) + rc = chmod(path, mode ?: 0755); + if ((st.st_uid != (uid_t)uid || st.st_gid != (gid_t)gid) && chown(path, uid, gid)) + warn("Failed chown(%s, %d, %d)", path, uid, gid); + } } umask(omask); break;