sd-bus: don't look for a 64bit value when we only have 32bit value on reply cookie hash table access

This broke hashtable lookups for the message cookies on s390x, which is
a 64bit BE machine where accessing 32bit values as 64bit and vice versa
will explode.

Also, while we are at it, be a bit more careful when dealing with the
64bit cookies we expose and the 32bit serial numbers dbus uses in its
payload.

Problem identified by Fridrich Strba.
This commit is contained in:
Lennart Poettering 2014-03-13 20:33:22 +01:00
parent 82923adfe5
commit 42c4ebcbd4
5 changed files with 22 additions and 16 deletions

View file

@ -69,10 +69,10 @@ int bus_message_dump(sd_bus_message *m, FILE *f, bool with_header) {
if (BUS_MESSAGE_COOKIE(m) == 0xFFFFFFFFULL)
fprintf(f, " Cookie=-1");
else
fprintf(f, " Cookie=%lu", (unsigned long) BUS_MESSAGE_COOKIE(m));
fprintf(f, " Cookie=%" PRIu64, BUS_MESSAGE_COOKIE(m));
if (m->reply_cookie != 0)
fprintf(f, " ReplyCookie=%lu", (unsigned long) m->reply_cookie);
fprintf(f, " ReplyCookie=%" PRIu64, m->reply_cookie);
fputs("\n", f);

View file

@ -266,7 +266,7 @@ static int bus_message_setup_kmsg(sd_bus *b, sd_bus_message *m) {
well_known ? 0 :
m->destination ? unique : KDBUS_DST_ID_BROADCAST;
m->kdbus->payload_type = KDBUS_PAYLOAD_DBUS;
m->kdbus->cookie = m->header->serial;
m->kdbus->cookie = (uint64_t) m->header->serial;
m->kdbus->priority = m->priority;
if (m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)

View file

@ -617,7 +617,7 @@ static int message_new_reply(
t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
t->reply_cookie = BUS_MESSAGE_COOKIE(call);
r = message_append_field_uint32(t, BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_cookie);
r = message_append_field_uint32(t, BUS_MESSAGE_HEADER_REPLY_SERIAL, (uint32_t) t->reply_cookie);
if (r < 0)
goto fail;
@ -752,7 +752,7 @@ int bus_message_new_synthetic_error(
t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
t->reply_cookie = cookie;
r = message_append_field_uint32(t, BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_cookie);
r = message_append_field_uint32(t, BUS_MESSAGE_HEADER_REPLY_SERIAL, (uint32_t) t->reply_cookie);
if (r < 0)
goto fail;
@ -5075,21 +5075,26 @@ int bus_message_parse_fields(sd_bus_message *m) {
break;
}
case BUS_MESSAGE_HEADER_REPLY_SERIAL:
case BUS_MESSAGE_HEADER_REPLY_SERIAL: {
uint32_t serial;
if (m->reply_cookie != 0)
return -EBADMSG;
if (!streq(signature, "u"))
return -EBADMSG;
r = message_peek_field_uint32(m, &ri, item_size, &m->reply_cookie);
r = message_peek_field_uint32(m, &ri, item_size, &serial);
if (r < 0)
return r;
m->reply_cookie = serial;
if (m->reply_cookie == 0)
return -EBADMSG;
break;
}
case BUS_MESSAGE_HEADER_UNIX_FDS:
if (unix_fds != 0)
@ -5489,7 +5494,7 @@ int bus_message_remarshal(sd_bus *bus, sd_bus_message **m) {
return -ENOMEM;
n->reply_cookie = (*m)->reply_cookie;
r = message_append_field_uint32(n, BUS_MESSAGE_HEADER_REPLY_SERIAL, n->reply_cookie);
r = message_append_field_uint32(n, BUS_MESSAGE_HEADER_REPLY_SERIAL, (uint32_t) n->reply_cookie);
if (r < 0)
return r;

View file

@ -84,7 +84,7 @@ struct sd_bus_message {
sd_bus *bus;
uint32_t reply_cookie;
uint64_t reply_cookie;
const char *path;
const char *interface;
@ -162,7 +162,8 @@ static inline uint64_t BUS_MESSAGE_BSWAP64(sd_bus_message *m, uint64_t u) {
return BUS_MESSAGE_NEED_BSWAP(m) ? bswap_64(u) : u;
}
static inline uint32_t BUS_MESSAGE_COOKIE(sd_bus_message *m) {
static inline uint64_t BUS_MESSAGE_COOKIE(sd_bus_message *m) {
/* Note that we return the serial converted to a 64bit value here */
return BUS_MESSAGE_BSWAP32(m, m->header->serial);
}

View file

@ -1486,15 +1486,15 @@ static int bus_write_message(sd_bus *bus, sd_bus_message *m, bool hint_sync_call
return r;
if (bus->is_kernel || *idx >= BUS_MESSAGE_SIZE(m))
log_debug("Sent message type=%s sender=%s destination=%s object=%s interface=%s member=%s cookie=%lu reply_cookie=%lu error=%s",
log_debug("Sent message type=%s sender=%s destination=%s object=%s interface=%s member=%s cookie=%" PRIu64 " reply_cookie=%" PRIu64 " error=%s",
bus_message_type_to_string(m->header->type),
strna(sd_bus_message_get_sender(m)),
strna(sd_bus_message_get_destination(m)),
strna(sd_bus_message_get_path(m)),
strna(sd_bus_message_get_interface(m)),
strna(sd_bus_message_get_member(m)),
(unsigned long) BUS_MESSAGE_COOKIE(m),
(unsigned long) m->reply_cookie,
BUS_MESSAGE_COOKIE(m),
m->reply_cookie,
strna(m->error.message));
return r;
@ -2253,15 +2253,15 @@ static int process_message(sd_bus *bus, sd_bus_message *m) {
bus->current = m;
bus->iteration_counter++;
log_debug("Got message type=%s sender=%s destination=%s object=%s interface=%s member=%s cookie=%lu reply_cookie=%lu error=%s",
log_debug("Got message type=%s sender=%s destination=%s object=%s interface=%s member=%s cookie=%" PRIu64 " reply_cookie=%" PRIu64 " error=%s",
bus_message_type_to_string(m->header->type),
strna(sd_bus_message_get_sender(m)),
strna(sd_bus_message_get_destination(m)),
strna(sd_bus_message_get_path(m)),
strna(sd_bus_message_get_interface(m)),
strna(sd_bus_message_get_member(m)),
(unsigned long) BUS_MESSAGE_COOKIE(m),
(unsigned long) m->reply_cookie,
BUS_MESSAGE_COOKIE(m),
m->reply_cookie,
strna(m->error.message));
r = process_hello(bus, m);