From: Lukasz Skalski Date: Wed, 25 May 2016 12:46:10 +0000 (+0200) Subject: kdbus: always pack message header as as single PAYLOAD_VEC item X-Git-Tag: accepted/tizen/common/20160530.131628^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4267655bc24521da58c89f6a42660638680c4229;p=platform%2Fupstream%2Fdbus.git kdbus: always pack message header as as single PAYLOAD_VEC item According to PORTING-DBUS1 document [1], the message header in its entirety must be contained in a single PAYLOAD_VEC item. What's more, in case of memfd transport, message footer (which contains body signature and offsets size) has to be attached at the end of message as a yet another PAYLOAD_VEC item. [1] https://cgit.freedesktop.org/systemd/systemd/tree/src/libsystemd/sd-bus/PORTING-DBUS1 Change-Id: I282589c0641c1eb97f874fcfd6e3bee6ecacc8ae --- diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c index 0792e11..e058b7a 100644 --- a/dbus/dbus-message.c +++ b/dbus/dbus-message.c @@ -4679,7 +4679,7 @@ _dbus_decode_kmsg (DBusString *data, if (n_unix_fds > n_fds) { _dbus_verbose("Message contains references to more unix fds than were sent %u != %u\n", - n_unix_fds, loader->n_unix_fds); + n_unix_fds, message->n_unix_fds); dbus_message_unref (message); return NULL; } diff --git a/dbus/dbus-transport-kdbus.c b/dbus/dbus-transport-kdbus.c index 80c5b3e..75cc180 100644 --- a/dbus/dbus-transport-kdbus.c +++ b/dbus/dbus-transport-kdbus.c @@ -504,30 +504,22 @@ parse_name (const char *name) static int prepare_mfd (int memfd, - const char *header, - uint64_t header_size, const char *body, uint64_t body_size) { - const char *data[] = { header, body }; - uint64_t count[] = { header_size, body_size }; int64_t wr; - size_t p; _dbus_verbose ("sending data via memfd\n"); - for (p = 0; p < sizeof (data) / sizeof (data[0]); ++p) + while (body_size) { - while (count[p]) + wr = write (memfd, body, body_size); + if (wr < 0) { - wr = write (memfd, data[p], count[p]); - if (wr < 0) - { - _dbus_verbose ("writing to memfd failed: (%d) %m\n", errno); - return -1; - } - count[p] -= wr; - data[p] += wr; + _dbus_verbose ("writing to memfd failed: (%d) %m\n", errno); + return -1; } + body_size -= wr; + body += wr; } // seal data - kdbus module needs it @@ -717,6 +709,7 @@ kdbus_write_msg_internal (DBusTransportKdbus *transport, int memfd = -1; const int *unix_fds; unsigned fds_count; + const char* header_data; DBusError error; dbus_uint64_t items_size; @@ -807,47 +800,79 @@ kdbus_write_msg_internal (DBusTransportKdbus *transport, /* build message contents */ item = msg->items; - if (memfd >= 0) + header_data = _dbus_string_get_const_data (header); + + _dbus_verbose ("sending data by vec\n"); + item = _kdbus_item_add_payload_vec (item, + header_size, + (uintptr_t)header_data); + if (body_size > 0) { - if (prepare_mfd (memfd, - _dbus_string_get_const_data (header), header_size, - _dbus_string_get_const_data (body), body_size) == -1) + const char* body_data = _dbus_string_get_const_data (body); + +#ifdef DBUS_ENABLE_VERBOSE_MODE + if (-1 != debug) { - ret_size = -1; - goto out; + debug_str ("Header to send:", header); + debug_str ("Body to send:", body); } +#endif - item = _kdbus_item_add_payload_memfd (item, - 0, - ret_size, - memfd); - } - else - { - const char* header_data = _dbus_string_get_const_data (header); - - _dbus_verbose ("sending data by vec\n"); - item = _kdbus_item_add_payload_vec (item, - header_size, - (uintptr_t)header_data); - if (body_size > 0) + if (memfd >= 0) { - const char* body_data = _dbus_string_get_const_data (body); -#ifdef DBUS_ENABLE_VERBOSE_MODE - if (-1 != debug) + size_t body_offsets_size; + const char *footer_ptr; + + /* determine body offsets size */ + if (ret_size <= 0xFF) + body_offsets_size = 1; + else if (ret_size <= 0xFFFF) + body_offsets_size = 2; + else if (ret_size <= 0xFFFFFFFF) + body_offsets_size = 4; + else + body_offsets_size = 8; + + /* check footer size */ + footer_ptr = body_data + body_size - body_offsets_size -1; + while (footer_ptr >= body_data && (*footer_ptr) != 0) + footer_ptr--; + + if (footer_ptr < body_data) { - debug_str ("Header to send:", header); - debug_str ("Body to send:", body); + ret_size = -1; + goto out; } -#endif + /* prepare memfd for body */ + if (prepare_mfd (memfd, + body_data, + (footer_ptr - body_data) * sizeof(char)) == -1) + { + ret_size = -1; + goto out; + } + + /* body */ + item = _kdbus_item_add_payload_memfd (item, + 0, + (footer_ptr - body_data) * sizeof(char), + memfd); + + /* footer */ + item = _kdbus_item_add_payload_vec (item, + (body_data + body_size - footer_ptr) * sizeof(char), + (uintptr_t)footer_ptr); + } + else + { while (body_size > 0) { dbus_uint64_t part_size = body_size; if (part_size > KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE) - part_size = KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE; + part_size = KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE; _dbus_verbose ("attaching body part\n"); item = _kdbus_item_add_payload_vec (item, @@ -856,8 +881,8 @@ kdbus_write_msg_internal (DBusTransportKdbus *transport, body_data += part_size; body_size -= part_size; } - } - } + } /* memfd */ + } /* body_size */ if (fds_count) item = _kdbus_item_add_fds (item, unix_fds, fds_count); diff --git a/dbus/kdbus-common.c b/dbus/kdbus-common.c index e0af233..c2c2e0c 100644 --- a/dbus/kdbus-common.c +++ b/dbus/kdbus-common.c @@ -698,16 +698,21 @@ _kdbus_compute_msg_items_size (kdbus_t *kdbus, { __u64 items_size = 0; + /* header */ + items_size += KDBUS_ITEM_SIZE (sizeof (struct kdbus_vec)); + if (use_memfd) { + /* body */ items_size += KDBUS_ITEM_SIZE (sizeof (struct kdbus_memfd)); + + /* footer */ + items_size += KDBUS_ITEM_SIZE (sizeof (struct kdbus_vec)); } else { __u64 vectors = (body_size + KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE - 1) / KDBUS_MSG_MAX_PAYLOAD_VEC_SIZE; - /* 1st vector -> for header */ - items_size += KDBUS_ITEM_SIZE (sizeof (struct kdbus_vec)); /* subsequent vectors -> parts of body */ items_size += vectors * KDBUS_ITEM_SIZE (sizeof (struct kdbus_vec)); }