Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP2:GA
systemd-mini.1472
0002-core-shared-in-deserializing-match-same-fi...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0002-core-shared-in-deserializing-match-same-files-reache.patch of Package systemd-mini.1472
Based on c78e47a61fa8d9a21fece01c83e4c26ce0938d27 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 --- src/core/socket.c | 6 +++--- src/shared/path-util.c | 19 +++++++++++++++++++ src/shared/path-util.h | 1 + src/shared/socket-util.c | 10 ++++------ 4 files changed, 27 insertions(+), 9 deletions(-) --- src/core/socket.c +++ src/core/socket.c 2015-06-16 00:00:00.000000000 +0000 @@ -1828,7 +1828,7 @@ static int socket_deserialize_item(Unit 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) { @@ -1848,7 +1848,7 @@ static int socket_deserialize_item(Unit 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) { @@ -1868,7 +1868,7 @@ static int socket_deserialize_item(Unit 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) { --- src/shared/path-util.c +++ src/shared/path-util.c 2015-06-16 11:14:35.877518595 +0000 @@ -28,6 +28,8 @@ #include <stdio.h> #include <fcntl.h> #include <dirent.h> +#include <sys/types.h> +#include <sys/stat.h> #include <sys/statvfs.h> #include "macro.h" @@ -323,6 +325,23 @@ bool path_equal(const char *a, const cha } } +static int files_same(const char *filea, const char *fileb) { + struct stat a, b; + + if (stat(filea, &a) < 0) + return -errno; + + if (stat(fileb, &b) < 0) + return -errno; + + return a.st_dev == b.st_dev && + a.st_ino == b.st_ino; +} + +bool path_equal_or_files_same(const char *a, const char *b) { + return path_equal(a, b) || files_same(a, b) > 0; +} + int path_is_mount_point(const char *t, bool allow_symlink) { char *parent; int r; --- src/shared/path-util.h +++ src/shared/path-util.h 2015-06-16 11:15:17.717518795 +0000 @@ -44,6 +44,7 @@ char* path_make_absolute_cwd(const char 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_strv_make_absolute_cwd(char **l); char** path_strv_canonicalize_absolute(char **l, const char *prefix); --- src/shared/socket-util.c +++ src/shared/socket-util.c 2015-06-16 00:00:00.000000000 +0000 @@ -324,9 +324,6 @@ bool socket_address_equal(const SocketAd 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; @@ -351,14 +348,16 @@ bool socket_address_equal(const SocketAd 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; } @@ -366,7 +365,6 @@ bool socket_address_equal(const SocketAd break; case AF_NETLINK: - if (a->protocol != b->protocol) return false;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor