forked from pool/systemd
.
OBS-URL: https://build.opensuse.org/package/show/Base:System/systemd?expand=0&rev=554
This commit is contained in:
parent
03f3ab857c
commit
2ae79a3aaf
@ -1,36 +1,86 @@
|
||||
From: Olaf Kirch <okir@suse.de>
|
||||
Date: Date: Wed, 12 Mar 2014 13:52:50 +0000
|
||||
Subject: [PATCH] systemd big endian reply matching
|
||||
---
|
||||
src/libsystemd/sd-bus/sd-bus.c | 36 +++++++++++++++++++++++++++++++-----
|
||||
1 file changed, 31 insertions(+), 5 deletions(-)
|
||||
|
||||
Reply matching on big endian architectures is broken in the dbus code.
|
||||
|
||||
The hashmap functions, which are used to store and retrieves the reply_callback
|
||||
structures of asynchronous calls, take a uint64_t pointer for the key argument.
|
||||
However, the reply_cookie of the sd_bus_message is stored in a 32bit variable.
|
||||
|
||||
This works nicely on x86-64, because (a) it's little endian, and (b) the struct
|
||||
is padded to the next 8 byte boundary because reply_cookie is wedged between
|
||||
two pointers.
|
||||
|
||||
On s390x, this fails badly thanks to being big endian.
|
||||
|
||||
Unfortunately, this results in complete failure of any communication
|
||||
between systemd daemons and the dbus-daemon, because it never gets
|
||||
past the initial Hello handshake - which is sent as an asynchronous
|
||||
message.
|
||||
|
||||
Signed-off-by: Olaf Kirch <okir@suse.de>
|
||||
|
||||
Index: systemd-210/src/libsystemd/sd-bus/bus-message.h
|
||||
Index: systemd-210/src/libsystemd/sd-bus/sd-bus.c
|
||||
===================================================================
|
||||
--- systemd-210/src/libsystemd/sd-bus/bus-message.h
|
||||
+++ systemd-210/src/libsystemd/sd-bus/bus-message.h
|
||||
@@ -84,7 +84,7 @@ struct sd_bus_message {
|
||||
--- systemd-210.orig/src/libsystemd/sd-bus/sd-bus.c
|
||||
+++ systemd-210/src/libsystemd/sd-bus/sd-bus.c
|
||||
@@ -358,6 +358,29 @@ _public_ int sd_bus_set_name(sd_bus *bus
|
||||
return 0;
|
||||
}
|
||||
|
||||
sd_bus *bus;
|
||||
+/*
|
||||
+ * Wrap the hashmap lookups in helper functions to ensure that the
|
||||
+ * cookie pointer is always cast to 64bit before passing it to any of the
|
||||
+ * hashmap functions
|
||||
+ */
|
||||
+static inline int bus_add_reply_callback(sd_bus *bus, struct reply_callback *c, uint64_t cookie)
|
||||
+{
|
||||
+ return hashmap_put(bus->reply_callbacks, &cookie, c);
|
||||
+}
|
||||
+
|
||||
+static inline struct reply_callback *bus_get_reply_callback(sd_bus *bus, uint64_t cookie)
|
||||
+{
|
||||
+ return hashmap_remove(bus->reply_callbacks, &cookie);
|
||||
+}
|
||||
+
|
||||
+static inline void bus_drop_reply_callback(sd_bus *bus, const struct reply_callback *c)
|
||||
+{
|
||||
+ struct reply_callback *cc;
|
||||
+
|
||||
+ cc = bus_get_reply_callback(bus, c->cookie);
|
||||
+ assert(cc == NULL || cc == c);
|
||||
+}
|
||||
+
|
||||
static int hello_callback(sd_bus *bus, sd_bus_message *reply, void *userdata, sd_bus_error *error) {
|
||||
const char *s;
|
||||
int r;
|
||||
@@ -1757,7 +1780,7 @@ _public_ int sd_bus_call_async(
|
||||
c->cookie = BUS_MESSAGE_COOKIE(m);
|
||||
c->timeout = calc_elapse(m->timeout);
|
||||
|
||||
- uint32_t reply_cookie;
|
||||
+ uint64_t reply_cookie;
|
||||
- r = hashmap_put(bus->reply_callbacks, &c->cookie, c);
|
||||
+ r = bus_add_reply_callback(bus, c, c->cookie);
|
||||
if (r < 0) {
|
||||
free(c);
|
||||
return r;
|
||||
@@ -1788,7 +1811,7 @@ _public_ int sd_bus_call_async_cancel(sd
|
||||
assert_return(cookie != 0, -EINVAL);
|
||||
assert_return(!bus_pid_changed(bus), -ECHILD);
|
||||
|
||||
const char *path;
|
||||
const char *interface;
|
||||
- c = hashmap_remove(bus->reply_callbacks, &cookie);
|
||||
+ c = bus_get_reply_callback(bus, cookie);
|
||||
if (!c)
|
||||
return 0;
|
||||
|
||||
@@ -2062,7 +2085,7 @@ static int process_timeout(sd_bus *bus)
|
||||
return r;
|
||||
|
||||
assert_se(prioq_pop(bus->reply_callbacks_prioq) == c);
|
||||
- hashmap_remove(bus->reply_callbacks, &c->cookie);
|
||||
+ bus_drop_reply_callback(bus, c->cookie);
|
||||
|
||||
bus->current = m;
|
||||
bus->iteration_counter ++;
|
||||
@@ -2110,7 +2133,9 @@ static int process_reply(sd_bus *bus, sd
|
||||
m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
|
||||
return 0;
|
||||
|
||||
- c = hashmap_remove(bus->reply_callbacks, &m->reply_cookie);
|
||||
+ /* caveat emptor: reply_cookie is 32bit, but the hashmap lookup uses a 64bit
|
||||
+ * cookie pointer - without type checking, */
|
||||
+ c = bus_get_reply_callback(bus, m->reply_cookie);
|
||||
if (!c)
|
||||
return 0;
|
||||
|
||||
@@ -2370,7 +2395,8 @@ static int process_closing(sd_bus *bus,
|
||||
if (c->timeout != 0)
|
||||
prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx);
|
||||
|
||||
- hashmap_remove(bus->reply_callbacks, &c->cookie);
|
||||
+ /* Remove callback from reply_callbacks hashmap */
|
||||
+ bus_drop_reply_callback(bus, c->cookie);
|
||||
|
||||
bus->current = m;
|
||||
bus->iteration_counter++;
|
||||
|
Loading…
Reference in New Issue
Block a user