dryang / rpms / systemd

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