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