--- src/libsystemd/sd-bus/sd-bus.c | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) Index: systemd-210/src/libsystemd/sd-bus/sd-bus.c =================================================================== --- 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; } +/* + * 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); - 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); - 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); 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); bus->current = m; bus->iteration_counter++;