]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tmpfiles: make create_fifo() safe
authorFranck Bui <fbui@suse.com>
Fri, 27 Apr 2018 16:17:32 +0000 (18:17 +0200)
committerFranck Bui <fbui@suse.com>
Mon, 30 Jul 2018 13:54:03 +0000 (15:54 +0200)
src/tmpfiles/tmpfiles.c

index a934cbff9199c54cc6c64b7789f7da88ab49db8d..71f8dec49b51fe64a8cc78a0371dd36feb393316 100644 (file)
@@ -1715,13 +1715,21 @@ static int create_device(Item *i, mode_t file_type) {
 }
 
 static int create_fifo(Item *i, const char *path) {
+        _cleanup_close_ int pfd = -1, fd = -1;
         CreationMode creation;
         struct stat st;
+        char *bn;
         int r;
 
+        pfd = path_open_parent_safe(path);
+        if (pfd < 0)
+                return pfd;
+
+        bn = basename(path);
+
         RUN_WITH_UMASK(0000) {
                 mac_selinux_create_file_prepare(path, S_IFIFO);
-                r = mkfifo(path, i->mode);
+                r = mkfifoat(pfd, bn, i->mode);
                 mac_selinux_create_file_clear();
         }
 
@@ -1729,7 +1737,7 @@ static int create_fifo(Item *i, const char *path) {
                 if (errno != EEXIST)
                         return log_error_errno(errno, "Failed to create fifo %s: %m", path);
 
-                if (lstat(path, &st) < 0)
+                if (fstatat(pfd, bn, &st, AT_SYMLINK_NOFOLLOW) < 0)
                         return log_error_errno(errno, "stat(%s) failed: %m", path);
 
                 if (!S_ISFIFO(st.st_mode)) {
@@ -1737,7 +1745,7 @@ static int create_fifo(Item *i, const char *path) {
                         if (i->force) {
                                 RUN_WITH_UMASK(0000) {
                                         mac_selinux_create_file_prepare(path, S_IFIFO);
-                                        r = mkfifo_atomic(path, i->mode);
+                                        r = mkfifoat_atomic(pfd, bn, i->mode);
                                         mac_selinux_create_file_clear();
                                 }
 
@@ -1752,9 +1760,14 @@ static int create_fifo(Item *i, const char *path) {
                         creation = CREATION_EXISTING;
         } else
                 creation = CREATION_NORMAL;
+
         log_debug("%s fifo \"%s\".", creation_mode_verb_to_string(creation), path);
 
-        return path_set_perms(i, path);
+        fd = openat(pfd, bn, O_NOFOLLOW|O_CLOEXEC|O_PATH);
+        if (fd < 0)
+                return log_error_errno(fd, "Failed to openat(%s): %m", path);
+
+        return fd_set_perms(i, fd, NULL);
 }
 
 typedef int (*action_t)(Item *, const char *);