[systemd-commits] 9 commits - src/libsystemd-bus
Lennart Poettering
lennart at kemper.freedesktop.org
Mon Dec 9 16:08:05 PST 2013
src/libsystemd-bus/bus-kernel.c | 18 +
src/libsystemd-bus/bus-message.c | 381 +++++++++++++++-----------------
src/libsystemd-bus/bus-socket.c | 7
src/libsystemd-bus/test-bus-zero-copy.c | 25 +-
4 files changed, 229 insertions(+), 202 deletions(-)
New commits:
commit 72d87e65192c688374688f98e579baeaf3b8175f
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Dec 10 01:07:32 2013 +0100
bus: beef up zero copy test case
diff --git a/src/libsystemd-bus/test-bus-zero-copy.c b/src/libsystemd-bus/test-bus-zero-copy.c
index 92a7398..0b72fe5 100644
--- a/src/libsystemd-bus/test-bus-zero-copy.c
+++ b/src/libsystemd-bus/test-bus-zero-copy.c
@@ -87,14 +87,17 @@ int main(int argc, char *argv[]) {
r = sd_bus_message_append_array_space(m, 'y', FIRST_ARRAY, (void**) &p);
assert_se(r >= 0);
- memset(p, 'L', FIRST_ARRAY);
+ p[0] = '<';
+ memset(p+1, 'L', FIRST_ARRAY-2);
+ p[FIRST_ARRAY-1] = '>';
r = sd_memfd_new_and_map(&f, STRING_SIZE, (void**) &s);
assert_se(r >= 0);
- for (i = 0; i < STRING_SIZE-1; i++)
+ s[0] = '<';
+ for (i = 1; i < STRING_SIZE-2; i++)
s[i] = '0' + (i % 10);
-
+ s[STRING_SIZE-2] = '>';
s[STRING_SIZE-1] = 0;
munmap(s, STRING_SIZE);
@@ -110,7 +113,9 @@ int main(int argc, char *argv[]) {
r = sd_memfd_new_and_map(&f, SECOND_ARRAY, (void**) &p);
assert_se(r >= 0);
- memset(p, 'P', SECOND_ARRAY);
+ p[0] = '<';
+ memset(p+1, 'P', SECOND_ARRAY-2);
+ p[SECOND_ARRAY-1] = '>';
munmap(p, SECOND_ARRAY);
r = sd_memfd_get_size(f, &sz);
@@ -151,22 +156,28 @@ int main(int argc, char *argv[]) {
assert_se(r > 0);
assert_se(l == FIRST_ARRAY);
- for (i = 0; i < l; i++)
+ assert_se(p[0] == '<');
+ for (i = 1; i < l-1; i++)
assert_se(p[i] == 'L');
+ assert_se(p[l-1] == '>');
r = sd_bus_message_read(m, "s", &s);
assert_se(r > 0);
- for (i = 0; i < STRING_SIZE-1; i++)
+ assert_se(s[0] == '<');
+ for (i = 1; i < STRING_SIZE-2; i++)
assert_se(s[i] == (char) ('0' + (i % 10)));
+ assert_se(s[STRING_SIZE-2] == '>');
assert_se(s[STRING_SIZE-1] == 0);
r = sd_bus_message_read_array(m, 'y', (const void**) &p, &l);
assert_se(r > 0);
assert_se(l == SECOND_ARRAY);
- for (i = 0; i < l; i++)
+ assert_se(p[0] == '<');
+ for (i = 1; i < l-1; i++)
assert_se(p[i] == 'P');
+ assert_se(p[l-1] == '>');
r = sd_bus_message_exit_container(m);
assert_se(r > 0);
commit e1d337d4626728545748302735e9e382b5741e83
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Dec 10 01:07:09 2013 +0100
bus: only accept gvariant native endian messages via kdbus
diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c
index a3afb2e..d0a9fbc 100644
--- a/src/libsystemd-bus/bus-kernel.c
+++ b/src/libsystemd-bus/bus-kernel.c
@@ -362,6 +362,7 @@ int bus_kernel_take_fd(sd_bus *b) {
b->is_kernel = true;
b->bus_client = true;
b->can_fds = !!(hello.conn_flags & KDBUS_HELLO_ACCEPT_FD);
+ b->message_version = 2;
/* the kernel told us the UUID of the underlying bus */
memcpy(b->server_id.bytes, hello.id128, sizeof(b->server_id.bytes));
@@ -676,6 +677,12 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
if (n_bytes != total)
return -EBADMSG;
+ /* on kdbus we only speak native endian gvariant, never dbus1
+ * marshalling or reverse endian */
+ if (h->version != 2 ||
+ h->endian != BUS_NATIVE_ENDIAN)
+ return -EPROTOTYPE;
+
r = bus_message_from_header(bus, h, sizeof(struct bus_header), fds, n_fds, NULL, seclabel, 0, &m);
if (r < 0)
return r;
@@ -885,9 +892,16 @@ int bus_kernel_read_message(sd_bus *bus) {
}
k = (struct kdbus_msg *)((uint8_t *)bus->kdbus_buffer + off);
- if (k->payload_type == KDBUS_PAYLOAD_DBUS)
+ if (k->payload_type == KDBUS_PAYLOAD_DBUS) {
r = bus_kernel_make_message(bus, k);
- else if (k->payload_type == KDBUS_PAYLOAD_KERNEL)
+
+ /* Anybody can send us invalid messages, let's just drop them. */
+ if (r == -EBADMSG || r == -EPROTOTYPE) {
+ log_error("Ignoring invalid message: %s", strerror(-r));
+ r = 0;
+ }
+
+ } else if (k->payload_type == KDBUS_PAYLOAD_KERNEL)
r = bus_kernel_translate_message(bus, k);
else
r = 0;
diff --git a/src/libsystemd-bus/bus-socket.c b/src/libsystemd-bus/bus-socket.c
index 69f78c9..a449ce0 100644
--- a/src/libsystemd-bus/bus-socket.c
+++ b/src/libsystemd-bus/bus-socket.c
@@ -623,6 +623,9 @@ int bus_socket_setup(sd_bus *b) {
if (getsockopt(b->input_fd, SOL_SOCKET, SO_PEERCRED, &b->ucred, &l) >= 0 && l >= sizeof(b->ucred))
b->ucred_valid = b->ucred.pid > 0;
+ b->is_kernel = false;
+ b->message_version = 1;
+
return 0;
}
@@ -765,6 +768,10 @@ int bus_socket_exec(sd_bus *b) {
close_nointr_nofail(s[1]);
b->output_fd = b->input_fd = s[0];
+ r = bus_socket_setup(b);
+ if (r < 0)
+ return r;
+
return bus_socket_start_auth(b);
}
commit d36b70313666b334cc01c0c2344070341f7d0eb3
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Dec 10 01:06:52 2013 +0100
bus: fix rewinding in gvariant messages
diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c
index 35a4678..55fb47b 100644
--- a/src/libsystemd-bus/bus-message.c
+++ b/src/libsystemd-bus/bus-message.c
@@ -4150,6 +4150,9 @@ _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
m->rindex = c->begin;
}
+ c->offset_index = 0;
+ c->item_size = c->n_offsets > 0 ? c->offsets[0] : c->end;
+
return !isempty(c->signature);
}
commit 5763192abfdfafa2ca7c14c7d48393f67f28eff7
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Dec 10 01:06:29 2013 +0100
bus: fix signature handling when exiting container
diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c
index 007fab4..35a4678 100644
--- a/src/libsystemd-bus/bus-message.c
+++ b/src/libsystemd-bus/bus-message.c
@@ -3911,6 +3911,7 @@ _public_ int sd_bus_message_enter_container(sd_bus_message *m,
_public_ int sd_bus_message_exit_container(sd_bus_message *m) {
struct bus_container *c;
+ unsigned saved;
int r;
assert_return(m, -EINVAL);
@@ -3942,7 +3943,10 @@ _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
c = message_get_container(m);
+ saved = c->index;
+ c->index = c->saved_index;
r = container_next_item(m, c, &m->rindex);
+ c->index = saved;
if (r < 0)
return r;
commit 0039a203b1fc343bb280d512396886a4aefa4a01
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Dec 10 01:05:23 2013 +0100
bus: properly deserialize gvariant fixed size arrays
diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c
index b86ef96..007fab4 100644
--- a/src/libsystemd-bus/bus-message.c
+++ b/src/libsystemd-bus/bus-message.c
@@ -2404,10 +2404,12 @@ _public_ int sd_bus_message_append_array_space(
assert_return(m, -EINVAL);
assert_return(!m->sealed, -EPERM);
- assert_return(bus_type_is_trivial(type), -EINVAL);
+ assert_return(bus_type_is_trivial(type) && type != SD_BUS_TYPE_BOOLEAN, -EINVAL);
assert_return(ptr || size == 0, -EINVAL);
assert_return(!m->poisoned, -ESTALE);
+ /* alignment and size of the trivial types (except bool) is
+ * identical for gvariant and dbus1 marshalling */
align = bus_type_get_alignment(type);
sz = bus_type_get_size(type);
@@ -2554,8 +2556,8 @@ _public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
part->size = size;
copy_fd = -1;
- message_extend_containers(m, size);
m->header->body_size += size;
+ message_extend_containers(m, size);
return sd_bus_message_close_container(m);
}
@@ -2969,8 +2971,12 @@ static int container_next_item(sd_bus_message *m, struct bus_container *c, size_
*rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
c->item_size = c->offsets[c->offset_index+1] - *rindex;
} else {
+
+ if (c->offset_index+1 >= (c->end-c->begin)/sz)
+ goto end;
+
/* Fixed-size array */
- *rindex += sz;
+ *rindex = c->begin + (c->offset_index+1) * sz;
c->item_size = sz;
}
commit d63850688da41981f43642fe95cf3d6e00c6d69c
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Dec 10 01:04:36 2013 +0100
bus: handler empty messages correctly when using gvariant marshalling
diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c
index 8113744..b86ef96 100644
--- a/src/libsystemd-bus/bus-message.c
+++ b/src/libsystemd-bus/bus-message.c
@@ -2026,7 +2026,7 @@ static int bus_message_close_struct(sd_bus_message *m, struct bus_container *c,
if (!BUS_MESSAGE_IS_GVARIANT(m))
return 0;
- p = c->signature;
+ p = strempty(c->signature);
while (*p != 0) {
size_t n;
@@ -2074,7 +2074,7 @@ static int bus_message_close_struct(sd_bus_message *m, struct bus_container *c,
if (!a)
return -ENOMEM;
- p = c->signature;
+ p = strempty(c->signature);
for (i = 0, j = 0; i < c->n_offsets; i++) {
unsigned k;
size_t n;
@@ -3554,12 +3554,20 @@ static int build_struct_offsets(
int r;
assert(m);
- assert(signature);
assert(item_size);
assert(offsets);
assert(n_offsets);
+ if (isempty(signature)) {
+ *item_size = 0;
+ *offsets = NULL;
+ *n_offsets = 0;
+ return 0;
+ }
+
sz = determine_word_size(size, 0);
+ if (sz <= 0)
+ return -EBADMSG;
/* First, loop over signature and count variable elements and
* elements in general. We use this to know how large the
@@ -5281,7 +5289,7 @@ _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complet
assert_return(m, NULL);
c = complete ? &m->root_container : message_get_container(m);
- return c->signature ?: "";
+ return strempty(c->signature);
}
_public_ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
commit f30976971ce902d2ca04157318f5f3c58d63399c
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Dec 10 01:03:41 2013 +0100
bus: suppress creating empty parts in messages
diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c
index 9b4da3d..8113744 100644
--- a/src/libsystemd-bus/bus-message.c
+++ b/src/libsystemd-bus/bus-message.c
@@ -1131,9 +1131,7 @@ static void message_extend_containers(sd_bus_message *m, size_t expand) {
}
static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz, bool add_offset) {
- struct bus_body_part *part = NULL;
- size_t start_body, end_body, padding, start_part, end_part, added;
- bool add_new_part;
+ size_t start_body, end_body, padding, added;
void *p;
int r;
@@ -1156,54 +1154,61 @@ static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz, boo
return NULL;
}
- add_new_part =
- m->n_body_parts <= 0 ||
- m->body_end->sealed ||
- padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
+ if (added > 0) {
+ struct bus_body_part *part = NULL;
+ bool add_new_part;
+
+ add_new_part =
+ m->n_body_parts <= 0 ||
+ m->body_end->sealed ||
+ padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
+
+ if (add_new_part) {
+ if (padding > 0) {
+ part = message_append_part(m);
+ if (!part)
+ return NULL;
+
+ part_zero(part, padding);
+ }
- if (add_new_part) {
- if (padding > 0) {
part = message_append_part(m);
if (!part)
return NULL;
- part_zero(part, padding);
- }
+ r = part_make_space(m, part, sz, &p);
+ if (r < 0)
+ return NULL;
+ } else {
+ struct bus_container *c;
+ void *op;
+ size_t os, start_part, end_part;
- part = message_append_part(m);
- if (!part)
- return NULL;
+ part = m->body_end;
+ op = part->data;
+ os = part->size;
- r = part_make_space(m, part, sz, &p);
- if (r < 0)
- return NULL;
- } else {
- struct bus_container *c;
- void *op;
- size_t os;
+ start_part = ALIGN_TO(part->size, align);
+ end_part = start_part + sz;
- part = m->body_end;
- op = part->data;
- os = part->size;
+ r = part_make_space(m, part, end_part, &p);
+ if (r < 0)
+ return NULL;
- start_part = ALIGN_TO(part->size, align);
- end_part = start_part + sz;
+ if (padding > 0) {
+ memset(p, 0, padding);
+ p = (uint8_t*) p + padding;
+ }
- r = part_make_space(m, part, end_part, &p);
- if (r < 0)
- return NULL;
+ /* Readjust pointers */
+ for (c = m->containers; c < m->containers + m->n_containers; c++)
+ c->array_size = adjust_pointer(c->array_size, op, os, part->data);
- if (padding > 0) {
- memset(p, 0, padding);
- p = (uint8_t*) p + padding;
+ m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
}
-
- /* Readjust pointers */
- for (c = m->containers; c < m->containers + m->n_containers; c++)
- c->array_size = adjust_pointer(c->array_size, op, os, part->data);
-
- m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
- }
+ } else
+ /* Return something that is not NULL and is aligned */
+ p = (uint8_t *) NULL + align;
m->header->body_size = end_body;
message_extend_containers(m, added);
commit 18f5b48f3f0679be4d23d0c279d5d780a9fa4e30
Author: Lennart Poettering <lennart at poettering.net>
Date: Mon Dec 9 23:24:17 2013 +0100
bus: rely on explicit eof check instead of checking when mapping payload
This allows us to drop quite a bit of code.
diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c
index 547fd5f..9b4da3d 100644
--- a/src/libsystemd-bus/bus-message.c
+++ b/src/libsystemd-bus/bus-message.c
@@ -3033,9 +3033,6 @@ static int message_peek_body(
assert(rindex);
assert(align > 0);
- if (message_end_of_array(m, *rindex))
- return 0;
-
start = ALIGN_TO((size_t) *rindex, align);
padding = start - *rindex;
end = start + nbytes;
@@ -3063,7 +3060,7 @@ static int message_peek_body(
if (ret)
*ret = q;
- return 1;
+ return 0;
}
static bool validate_nul(const char *s, size_t l) {
@@ -3142,7 +3139,7 @@ _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
bool ok;
r = message_peek_body(m, &rindex, 1, c->item_size, &q);
- if (r <= 0)
+ if (r < 0)
return r;
if (type == SD_BUS_TYPE_STRING)
@@ -3169,7 +3166,7 @@ _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
assert(align > 0);
r = message_peek_body(m, &rindex, align, c->item_size, &q);
- if (r <= 0)
+ if (r < 0)
return r;
switch (type) {
@@ -3233,15 +3230,13 @@ _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
bool ok;
r = message_peek_body(m, &rindex, 4, 4, &q);
- if (r <= 0)
+ if (r < 0)
return r;
l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
r = message_peek_body(m, &rindex, 1, l+1, &q);
if (r < 0)
return r;
- if (r == 0)
- return -EBADMSG;
if (type == SD_BUS_TYPE_OBJECT_PATH)
ok = validate_object_path(q, l);
@@ -3257,15 +3252,13 @@ _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
uint8_t l;
r = message_peek_body(m, &rindex, 1, 1, &q);
- if (r <= 0)
+ if (r < 0)
return r;
l = *(uint8_t*) q;
r = message_peek_body(m, &rindex, 1, l+1, &q);
if (r < 0)
return r;
- if (r == 0)
- return -EBADMSG;
if (!validate_signature(q, l))
return -EBADMSG;
@@ -3283,7 +3276,7 @@ _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
assert(sz > 0);
r = message_peek_body(m, &rindex, align, sz, &q);
- if (r <= 0)
+ if (r < 0)
return r;
switch (type) {
@@ -3382,7 +3375,7 @@ static int bus_message_enter_array(
/* dbus1 */
r = message_peek_body(m, &rindex, 4, 4, &q);
- if (r <= 0)
+ if (r < 0)
return r;
if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
@@ -3395,8 +3388,6 @@ static int bus_message_enter_array(
r = message_peek_body(m, &rindex, alignment, 0, NULL);
if (r < 0)
return r;
- if (r == 0)
- return -EBADMSG;
*array_size = (uint32_t*) q;
@@ -3425,8 +3416,6 @@ static int bus_message_enter_array(
r = message_peek_body(m, &where, 1, sz, &q);
if (r < 0)
return r;
- if (r == 0)
- return -EBADMSG;
framing = read_word_le(q, sz);
if (framing > c->item_size - sz)
@@ -3440,8 +3429,6 @@ static int bus_message_enter_array(
r = message_peek_body(m, &where, 1, *n_offsets * sz, &q);
if (r < 0)
return r;
- if (r == 0)
- return -EBADMSG;
*offsets = new(size_t, *n_offsets);
if (!*offsets)
@@ -3512,8 +3499,6 @@ static int bus_message_enter_variant(
r = message_peek_body(m, &where, 1, 1+k, &q);
if (r < 0)
return r;
- if (r == 0)
- return -EBADMSG;
if (*(char*) q != 0)
return -EBADMSG;
@@ -3527,15 +3512,11 @@ static int bus_message_enter_variant(
r = message_peek_body(m, &rindex, 1, 1, &q);
if (r < 0)
return r;
- if (r == 0)
- return -EBADMSG;
l = *(uint8_t*) q;
r = message_peek_body(m, &rindex, 1, l+1, &q);
if (r < 0)
return r;
- if (r == 0)
- return -EBADMSG;
if (!validate_signature(q, l))
return -EBADMSG;
@@ -3613,8 +3594,6 @@ static int build_struct_offsets(
r = message_peek_body(m, &where, 1, n_variable * sz, &q);
if (r < 0)
return r;
- if (r == 0)
- return -EBADMSG;
v = n_variable;
@@ -3704,7 +3683,7 @@ static int enter_struct_or_dict_entry(
/* dbus1 */
r = message_peek_body(m, &m->rindex, 8, 0, NULL);
- if (r <= 0)
+ if (r < 0)
return r;
} else if (c->item_size <= 0) {
@@ -3823,7 +3802,7 @@ _public_ int sd_bus_message_enter_container(sd_bus_message *m,
/* Allow entering into anonymous containers */
r = sd_bus_message_peek_type(m, &tt, &cc);
- if (r <= 0)
+ if (r < 0)
return r;
if (type != 0 && type != tt)
@@ -4076,8 +4055,6 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char
r = message_peek_body(m, &where, 1, k, &q);
if (r < 0)
return r;
- if (r == 0)
- goto eof;
if (*(char*) q == 0)
break;
@@ -4102,15 +4079,11 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char
r = message_peek_body(m, &rindex, 1, 1, &q);
if (r < 0)
return r;
- if (r == 0)
- goto eof;
l = *(uint8_t*) q;
r = message_peek_body(m, &rindex, 1, l+1, &q);
if (r < 0)
return r;
- if (r == 0)
- return -EBADMSG;
if (!validate_signature(q, l))
return -EBADMSG;
@@ -4540,7 +4513,7 @@ _public_ int sd_bus_message_read_array(sd_bus_message *m,
if (align < 0)
return align;
- sz = c->item_size;
+ sz = c->end - c->begin;
} else {
align = bus_type_get_alignment(type);
if (align < 0)
@@ -4557,10 +4530,6 @@ _public_ int sd_bus_message_read_array(sd_bus_message *m,
r = message_peek_body(m, &m->rindex, align, sz, &p);
if (r < 0)
goto fail;
- if (r == 0) {
- r = -EBADMSG;
- goto fail;
- }
}
r = sd_bus_message_exit_container(m);
commit 813892259bf6f876975717cee6e2aa2e5b2c451a
Author: Lennart Poettering <lennart at poettering.net>
Date: Mon Dec 9 23:16:14 2013 +0100
bus: rearrange bus-message.c function order to keep read and write calls together
diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c
index 2e355a7..547fd5f 100644
--- a/src/libsystemd-bus/bus-message.c
+++ b/src/libsystemd-bus/bus-message.c
@@ -2662,6 +2662,112 @@ _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
return sd_bus_message_close_container(m);
}
+static int bus_message_close_header(sd_bus_message *m) {
+ uint8_t *a;
+ size_t sz, i;
+
+ assert(m);
+
+ if (!BUS_MESSAGE_IS_GVARIANT(m))
+ return 0;
+
+ if (m->n_header_offsets < 1)
+ return 0;
+
+ assert(m->header->fields_size == m->header_offsets[m->n_header_offsets-1]);
+
+ sz = determine_word_size(m->header->fields_size, m->n_header_offsets);
+
+ a = message_extend_fields(m, 1, sz * m->n_header_offsets, false);
+ if (!a)
+ return -ENOMEM;
+
+ for (i = 0; i < m->n_header_offsets; i++)
+ write_word_le(a + sz*i, sz, m->header_offsets[i]);
+
+ return 0;
+}
+
+int bus_message_seal(sd_bus_message *m, uint64_t serial) {
+ struct bus_body_part *part;
+ size_t l, a;
+ unsigned i;
+ int r;
+
+ assert(m);
+
+ if (m->sealed)
+ return -EPERM;
+
+ if (m->n_containers > 0)
+ return -EBADMSG;
+
+ if (m->poisoned)
+ return -ESTALE;
+
+ /* In vtables the return signature of method calls is listed,
+ * let's check if they match if this is a response */
+ if (m->header->type == SD_BUS_MESSAGE_METHOD_RETURN &&
+ m->enforced_reply_signature &&
+ !streq(strempty(m->root_container.signature), m->enforced_reply_signature))
+ return -ENOMSG;
+
+ /* If gvariant marshalling is used we need to close the body structure */
+ r = bus_message_close_struct(m, &m->root_container, false);
+ if (r < 0)
+ return r;
+
+ /* If there's a non-trivial signature set, then add it in here */
+ if (!isempty(m->root_container.signature)) {
+ r = message_append_field_signature(m, BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
+ if (r < 0)
+ return r;
+ }
+
+ if (m->n_fds > 0) {
+ r = message_append_field_uint32(m, BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
+ if (r < 0)
+ return r;
+ }
+
+ r = bus_message_close_header(m);
+ if (r < 0)
+ return r;
+
+ m->header->serial = serial;
+
+ /* Add padding at the end of the fields part, since we know
+ * the body needs to start at an 8 byte alignment. We made
+ * sure we allocated enough space for this, so all we need to
+ * do here is to zero it out. */
+ l = BUS_MESSAGE_FIELDS_SIZE(m);
+ a = ALIGN8(l) - l;
+ if (a > 0)
+ memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
+
+ /* If this is something we can send as memfd, then let's seal
+ the memfd now. Note that we can send memfds as payload only
+ for directed messages, and not for broadcasts. */
+ if (m->destination && m->bus && m->bus->use_memfd) {
+ MESSAGE_FOREACH_PART(part, i, m)
+ if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
+ bus_body_part_unmap(part);
+
+ if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
+ part->sealed = true;
+ }
+ }
+
+ m->root_container.end = BUS_MESSAGE_BODY_SIZE(m);
+ m->root_container.index = 0;
+ m->root_container.offset_index = 0;
+ m->root_container.item_size = m->root_container.n_offsets > 0 ? m->root_container.offsets[0] : 0;
+
+ m->sealed = true;
+
+ return 0;
+}
+
int bus_body_part_map(struct bus_body_part *part) {
void *p;
size_t psz;
@@ -5035,112 +5141,6 @@ int bus_message_parse_fields(sd_bus_message *m) {
return 0;
}
-static int bus_message_close_header(sd_bus_message *m) {
- uint8_t *a;
- size_t sz, i;
-
- assert(m);
-
- if (!BUS_MESSAGE_IS_GVARIANT(m))
- return 0;
-
- if (m->n_header_offsets < 1)
- return 0;
-
- assert(m->header->fields_size == m->header_offsets[m->n_header_offsets-1]);
-
- sz = determine_word_size(m->header->fields_size, m->n_header_offsets);
-
- a = message_extend_fields(m, 1, sz * m->n_header_offsets, false);
- if (!a)
- return -ENOMEM;
-
- for (i = 0; i < m->n_header_offsets; i++)
- write_word_le(a + sz*i, sz, m->header_offsets[i]);
-
- return 0;
-}
-
-int bus_message_seal(sd_bus_message *m, uint64_t serial) {
- struct bus_body_part *part;
- size_t l, a;
- unsigned i;
- int r;
-
- assert(m);
-
- if (m->sealed)
- return -EPERM;
-
- if (m->n_containers > 0)
- return -EBADMSG;
-
- if (m->poisoned)
- return -ESTALE;
-
- /* In vtables the return signature of method calls is listed,
- * let's check if they match if this is a response */
- if (m->header->type == SD_BUS_MESSAGE_METHOD_RETURN &&
- m->enforced_reply_signature &&
- !streq(strempty(m->root_container.signature), m->enforced_reply_signature))
- return -ENOMSG;
-
- /* If gvariant marshalling is used we need to close the body structure */
- r = bus_message_close_struct(m, &m->root_container, false);
- if (r < 0)
- return r;
-
- /* If there's a non-trivial signature set, then add it in here */
- if (!isempty(m->root_container.signature)) {
- r = message_append_field_signature(m, BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
- if (r < 0)
- return r;
- }
-
- if (m->n_fds > 0) {
- r = message_append_field_uint32(m, BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
- if (r < 0)
- return r;
- }
-
- r = bus_message_close_header(m);
- if (r < 0)
- return r;
-
- m->header->serial = serial;
-
- /* Add padding at the end of the fields part, since we know
- * the body needs to start at an 8 byte alignment. We made
- * sure we allocated enough space for this, so all we need to
- * do here is to zero it out. */
- l = BUS_MESSAGE_FIELDS_SIZE(m);
- a = ALIGN8(l) - l;
- if (a > 0)
- memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
-
- /* If this is something we can send as memfd, then let's seal
- the memfd now. Note that we can send memfds as payload only
- for directed messages, and not for broadcasts. */
- if (m->destination && m->bus && m->bus->use_memfd) {
- MESSAGE_FOREACH_PART(part, i, m)
- if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
- bus_body_part_unmap(part);
-
- if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
- part->sealed = true;
- }
- }
-
- m->root_container.end = BUS_MESSAGE_BODY_SIZE(m);
- m->root_container.index = 0;
- m->root_container.offset_index = 0;
- m->root_container.item_size = m->root_container.n_offsets > 0 ? m->root_container.offsets[0] : 0;
-
- m->sealed = true;
-
- return 0;
-}
-
_public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
assert_return(m, -EINVAL);
assert_return(destination, -EINVAL);
More information about the systemd-commits
mailing list