]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
ask-password-api: don't accidentally create a dir, when we don't want one
authorLennart Poettering <lennart@poettering.net>
Fri, 18 Oct 2024 19:36:34 +0000 (21:36 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 21 Oct 2024 12:14:16 +0000 (14:14 +0200)
Previously, we were using touch(), which usually works fine, because the
path should always refer to an existing directory, in which case it just
updates the timestamp. However, if the dir does not exist yet (which
shouldn't happen), it would be created as regular file, which is just
wrong.

Hence, let's instead create the dir as dir if it is missing, and then
update its timestamp.

src/basic/fs-util.c
src/basic/fs-util.h
src/shared/ask-password-api.c

index 97f36df8e7dfcd7b0ab5a35f7e5c9adbb40d3f54..35cebfc849a6c9450f6a0c98cdfbb9cb76a6c8d3 100644 (file)
@@ -371,9 +371,21 @@ int fd_warn_permissions(const char *path, int fd) {
         return stat_warn_permissions(path, &st);
 }
 
+int touch_fd(int fd, usec_t stamp) {
+        assert(fd >= 0);
+
+        if (stamp == USEC_INFINITY)
+                return futimens_opath(fd, /* ts= */ NULL);
+
+        struct timespec ts[2];
+        timespec_store(ts + 0, stamp);
+        ts[1] = ts[0];
+        return futimens_opath(fd, ts);
+}
+
 int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode) {
         _cleanup_close_ int fd = -EBADF;
-        int r, ret;
+        int ret;
 
         assert(path);
 
@@ -405,15 +417,7 @@ int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gi
          * something fchown(), fchmod(), futimensat() don't allow. */
         ret = fchmod_and_chown(fd, mode, uid, gid);
 
-        if (stamp != USEC_INFINITY) {
-                struct timespec ts;
-                timespec_store(&ts, stamp);
-
-                r = futimens_opath(fd, (const struct timespec[2]) { ts, ts });
-        } else
-                r = futimens_opath(fd, /* ts = */ NULL);
-
-        return RET_GATHER(ret, r);
+        return RET_GATHER(ret, touch_fd(fd, stamp));
 }
 
 int symlinkat_idempotent(const char *from, int atfd, const char *to, bool make_relative) {
index 06c95a3b080c4872e1d9ce25c82c48a678bc82c6..93af685eef2aac2def7cdaa5cc892f2af3e71e15 100644 (file)
@@ -54,6 +54,8 @@ int stat_warn_permissions(const char *path, const struct stat *st);
 #define access_nofollow(path, mode)                                             \
         RET_NERRNO(faccessat(AT_FDCWD, (path), (mode), AT_SYMLINK_NOFOLLOW))
 
+int touch_fd(int fd, usec_t stamp);
+
 int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode);
 
 static inline int touch(const char *path) {
index 1c4f357fbe4f9252bbe7a0941acda4caf247ad16..7b9cdadc547b3d7b231f37e152bbf698ee5fc96d 100644 (file)
@@ -102,7 +102,11 @@ static int touch_ask_password_directory(AskPasswordFlags flags) {
         if (r <= 0)
                 return r;
 
-        r = touch(p);
+        _cleanup_close_ int fd = open_mkdir(p, O_CLOEXEC, 0755);
+        if (fd < 0)
+                return fd;
+
+        r = touch_fd(fd, USEC_INFINITY);
         if (r < 0)
                 return r;