Zbigniew Jędrzejewski-Szmek 399a2a
From 25e6978bb35805349c69d610c775cfd3a70058f7 Mon Sep 17 00:00:00 2001
Zbigniew Jędrzejewski-Szmek 399a2a
From: Michal Schmidt <mschmidt@redhat.com>
Zbigniew Jędrzejewski-Szmek 399a2a
Date: Thu, 19 Feb 2015 23:12:38 +0100
Zbigniew Jędrzejewski-Szmek 399a2a
Subject: [PATCH] core, shared: in deserializing, match same files reached via
Zbigniew Jędrzejewski-Szmek 399a2a
 different paths
Zbigniew Jędrzejewski-Szmek 399a2a
Zbigniew Jędrzejewski-Szmek 399a2a
When dbus.socket is updated like this:
Zbigniew Jędrzejewski-Szmek 399a2a
-ListenStream=/var/run/dbus/system_bus_socket
Zbigniew Jędrzejewski-Szmek 399a2a
+ListenStream=/run/dbus/system_bus_socket
Zbigniew Jędrzejewski-Szmek 399a2a
... and daemon-reload is performed, bad things happen.
Zbigniew Jędrzejewski-Szmek 399a2a
During deserialization systemd does not recognize that the two paths
Zbigniew Jędrzejewski-Szmek 399a2a
refer to the same named socket and replaces the socket file with a new
Zbigniew Jędrzejewski-Szmek 399a2a
one. As a result, applications hang when they try talking to dbus.
Zbigniew Jędrzejewski-Szmek 399a2a
Zbigniew Jędrzejewski-Szmek 399a2a
Fix this by finding a match not only when the path names are equal, but
Zbigniew Jędrzejewski-Szmek 399a2a
also when they point to the same inode.
Zbigniew Jędrzejewski-Szmek 399a2a
In socket_address_equal() it is necessary to move the address size
Zbigniew Jędrzejewski-Szmek 399a2a
comparison into the abstract sockets branch. For path name sockets the
Zbigniew Jędrzejewski-Szmek 399a2a
comparison must not be done and for other families it is redundant
Zbigniew Jędrzejewski-Szmek 399a2a
(their sizes are constant and checked by socket_address_verify()).
Zbigniew Jędrzejewski-Szmek 399a2a
Zbigniew Jędrzejewski-Szmek 399a2a
FIFOs and special files can also have multiple pathnames, so compare the
Zbigniew Jędrzejewski-Szmek 399a2a
inodes for them as well. Note that previously the pathname checks used
Zbigniew Jędrzejewski-Szmek 399a2a
streq_ptr(), but the paths cannot be NULL.
Zbigniew Jędrzejewski-Szmek 399a2a
Zbigniew Jędrzejewski-Szmek 399a2a
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1186018
Zbigniew Jędrzejewski-Szmek 399a2a
(cherry picked from commit c78e47a61fa8d9a21fece01c83e4c26ce0938d27)
Zbigniew Jędrzejewski-Szmek 399a2a
---
Zbigniew Jędrzejewski-Szmek 399a2a
 src/core/socket.c        |  6 +++---
Zbigniew Jędrzejewski-Szmek 399a2a
 src/shared/path-util.c   |  4 ++++
Zbigniew Jędrzejewski-Szmek 399a2a
 src/shared/path-util.h   |  1 +
Zbigniew Jędrzejewski-Szmek 399a2a
 src/shared/socket-util.c | 10 ++++------
Zbigniew Jędrzejewski-Szmek 399a2a
 4 files changed, 12 insertions(+), 9 deletions(-)
Zbigniew Jędrzejewski-Szmek 399a2a
Zbigniew Jędrzejewski-Szmek 399a2a
diff --git a/src/core/socket.c b/src/core/socket.c
Zbigniew Jędrzejewski-Szmek 399a2a
index 48c43a2880..88aae4815b 100644
Zbigniew Jędrzejewski-Szmek 399a2a
--- a/src/core/socket.c
Zbigniew Jędrzejewski-Szmek 399a2a
+++ b/src/core/socket.c
Zbigniew Jędrzejewski-Szmek 399a2a
@@ -2100,7 +2100,7 @@ static int socket_deserialize_item(Unit *u, const char *key, const char *value,
Zbigniew Jędrzejewski-Szmek 399a2a
 
Zbigniew Jędrzejewski-Szmek 399a2a
                         LIST_FOREACH(port, p, s->ports)
Zbigniew Jędrzejewski-Szmek 399a2a
                                 if (p->type == SOCKET_FIFO &&
Zbigniew Jędrzejewski-Szmek 399a2a
-                                    streq_ptr(p->path, value+skip))
Zbigniew Jędrzejewski-Szmek 399a2a
+                                    path_equal_or_files_same(p->path, value+skip))
Zbigniew Jędrzejewski-Szmek 399a2a
                                         break;
Zbigniew Jędrzejewski-Szmek 399a2a
 
Zbigniew Jędrzejewski-Szmek 399a2a
                         if (p) {
Zbigniew Jędrzejewski-Szmek 399a2a
@@ -2119,7 +2119,7 @@ static int socket_deserialize_item(Unit *u, const char *key, const char *value,
Zbigniew Jędrzejewski-Szmek 399a2a
 
Zbigniew Jędrzejewski-Szmek 399a2a
                         LIST_FOREACH(port, p, s->ports)
Zbigniew Jędrzejewski-Szmek 399a2a
                                 if (p->type == SOCKET_SPECIAL &&
Zbigniew Jędrzejewski-Szmek 399a2a
-                                    streq_ptr(p->path, value+skip))
Zbigniew Jędrzejewski-Szmek 399a2a
+                                    path_equal_or_files_same(p->path, value+skip))
Zbigniew Jędrzejewski-Szmek 399a2a
                                         break;
Zbigniew Jędrzejewski-Szmek 399a2a
 
Zbigniew Jędrzejewski-Szmek 399a2a
                         if (p) {
Zbigniew Jędrzejewski-Szmek 399a2a
@@ -2138,7 +2138,7 @@ static int socket_deserialize_item(Unit *u, const char *key, const char *value,
Zbigniew Jędrzejewski-Szmek 399a2a
 
Zbigniew Jędrzejewski-Szmek 399a2a
                         LIST_FOREACH(port, p, s->ports)
Zbigniew Jędrzejewski-Szmek 399a2a
                                 if (p->type == SOCKET_MQUEUE &&
Zbigniew Jędrzejewski-Szmek 399a2a
-                                    streq_ptr(p->path, value+skip))
Zbigniew Jędrzejewski-Szmek 399a2a
+                                    streq(p->path, value+skip))
Zbigniew Jędrzejewski-Szmek 399a2a
                                         break;
Zbigniew Jędrzejewski-Szmek 399a2a
 
Zbigniew Jędrzejewski-Szmek 399a2a
                         if (p) {
Zbigniew Jędrzejewski-Szmek 399a2a
diff --git a/src/shared/path-util.c b/src/shared/path-util.c
Zbigniew Jędrzejewski-Szmek 399a2a
index b9db7f1047..70bc1caa2a 100644
Zbigniew Jędrzejewski-Szmek 399a2a
--- a/src/shared/path-util.c
Zbigniew Jędrzejewski-Szmek 399a2a
+++ b/src/shared/path-util.c
Zbigniew Jędrzejewski-Szmek 399a2a
@@ -436,6 +436,10 @@ bool path_equal(const char *a, const char *b) {
Zbigniew Jędrzejewski-Szmek 399a2a
         }
Zbigniew Jędrzejewski-Szmek 399a2a
 }
Zbigniew Jędrzejewski-Szmek 399a2a
 
Zbigniew Jędrzejewski-Szmek 399a2a
+bool path_equal_or_files_same(const char *a, const char *b) {
Zbigniew Jędrzejewski-Szmek 399a2a
+        return path_equal(a, b) || files_same(a, b) > 0;
Zbigniew Jędrzejewski-Szmek 399a2a
+}
Zbigniew Jędrzejewski-Szmek 399a2a
+
Zbigniew Jędrzejewski-Szmek 399a2a
 char* path_join(const char *root, const char *path, const char *rest) {
Zbigniew Jędrzejewski-Szmek 399a2a
         assert(path);
Zbigniew Jędrzejewski-Szmek 399a2a
 
Zbigniew Jędrzejewski-Szmek 399a2a
diff --git a/src/shared/path-util.h b/src/shared/path-util.h
Zbigniew Jędrzejewski-Szmek 399a2a
index bd0d32473f..bcf116ed3d 100644
Zbigniew Jędrzejewski-Szmek 399a2a
--- a/src/shared/path-util.h
Zbigniew Jędrzejewski-Szmek 399a2a
+++ b/src/shared/path-util.h
Zbigniew Jędrzejewski-Szmek 399a2a
@@ -45,6 +45,7 @@ int path_make_relative(const char *from_dir, const char *to_path, char **_r);
Zbigniew Jędrzejewski-Szmek 399a2a
 char* path_kill_slashes(char *path);
Zbigniew Jędrzejewski-Szmek 399a2a
 char* path_startswith(const char *path, const char *prefix) _pure_;
Zbigniew Jędrzejewski-Szmek 399a2a
 bool path_equal(const char *a, const char *b) _pure_;
Zbigniew Jędrzejewski-Szmek 399a2a
+bool path_equal_or_files_same(const char *a, const char *b);
Zbigniew Jędrzejewski-Szmek 399a2a
 char* path_join(const char *root, const char *path, const char *rest);
Zbigniew Jędrzejewski-Szmek 399a2a
 
Zbigniew Jędrzejewski-Szmek 399a2a
 char** path_strv_make_absolute_cwd(char **l);
Zbigniew Jędrzejewski-Szmek 399a2a
diff --git a/src/shared/socket-util.c b/src/shared/socket-util.c
Zbigniew Jędrzejewski-Szmek 399a2a
index c6f64876be..c278d6f9d4 100644
Zbigniew Jędrzejewski-Szmek 399a2a
--- a/src/shared/socket-util.c
Zbigniew Jędrzejewski-Szmek 399a2a
+++ b/src/shared/socket-util.c
Zbigniew Jędrzejewski-Szmek 399a2a
@@ -325,9 +325,6 @@ bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) {
Zbigniew Jędrzejewski-Szmek 399a2a
         if (a->type != b->type)
Zbigniew Jędrzejewski-Szmek 399a2a
                 return false;
Zbigniew Jędrzejewski-Szmek 399a2a
 
Zbigniew Jędrzejewski-Szmek 399a2a
-        if (a->size != b->size)
Zbigniew Jędrzejewski-Szmek 399a2a
-                return false;
Zbigniew Jędrzejewski-Szmek 399a2a
-
Zbigniew Jędrzejewski-Szmek 399a2a
         if (socket_address_family(a) != socket_address_family(b))
Zbigniew Jędrzejewski-Szmek 399a2a
                 return false;
Zbigniew Jędrzejewski-Szmek 399a2a
 
Zbigniew Jędrzejewski-Szmek 399a2a
@@ -352,14 +349,16 @@ bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) {
Zbigniew Jędrzejewski-Szmek 399a2a
                 break;
Zbigniew Jędrzejewski-Szmek 399a2a
 
Zbigniew Jędrzejewski-Szmek 399a2a
         case AF_UNIX:
Zbigniew Jędrzejewski-Szmek 399a2a
-
Zbigniew Jędrzejewski-Szmek 399a2a
                 if ((a->sockaddr.un.sun_path[0] == 0) != (b->sockaddr.un.sun_path[0] == 0))
Zbigniew Jędrzejewski-Szmek 399a2a
                         return false;
Zbigniew Jędrzejewski-Szmek 399a2a
 
Zbigniew Jędrzejewski-Szmek 399a2a
                 if (a->sockaddr.un.sun_path[0]) {
Zbigniew Jędrzejewski-Szmek 399a2a
-                        if (!strneq(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, sizeof(a->sockaddr.un.sun_path)))
Zbigniew Jędrzejewski-Szmek 399a2a
+                        if (!path_equal_or_files_same(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path))
Zbigniew Jędrzejewski-Szmek 399a2a
                                 return false;
Zbigniew Jędrzejewski-Szmek 399a2a
                 } else {
Zbigniew Jędrzejewski-Szmek 399a2a
+                        if (a->size != b->size)
Zbigniew Jędrzejewski-Szmek 399a2a
+                                return false;
Zbigniew Jędrzejewski-Szmek 399a2a
+
Zbigniew Jędrzejewski-Szmek 399a2a
                         if (memcmp(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, a->size) != 0)
Zbigniew Jędrzejewski-Szmek 399a2a
                                 return false;
Zbigniew Jędrzejewski-Szmek 399a2a
                 }
Zbigniew Jędrzejewski-Szmek 399a2a
@@ -367,7 +366,6 @@ bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) {
Zbigniew Jędrzejewski-Szmek 399a2a
                 break;
Zbigniew Jędrzejewski-Szmek 399a2a
 
Zbigniew Jędrzejewski-Szmek 399a2a
         case AF_NETLINK:
Zbigniew Jędrzejewski-Szmek 399a2a
-
Zbigniew Jędrzejewski-Szmek 399a2a
                 if (a->protocol != b->protocol)
Zbigniew Jędrzejewski-Szmek 399a2a
                         return false;
Zbigniew Jędrzejewski-Szmek 399a2a