summaryrefslogtreecommitdiff
path: root/src/libsystemd/sd-bus/bus-message.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsystemd/sd-bus/bus-message.c')
-rw-r--r--src/libsystemd/sd-bus/bus-message.c373
1 files changed, 185 insertions, 188 deletions
diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
index 8d92bc2002..bb7e09c945 100644
--- a/src/libsystemd/sd-bus/bus-message.c
+++ b/src/libsystemd/sd-bus/bus-message.c
@@ -1,6 +1,4 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
-/***
-***/
#include <errno.h>
#include <fcntl.h>
@@ -77,19 +75,38 @@ static void message_reset_parts(sd_bus_message *m) {
m->cached_rindex_part_begin = 0;
}
-static void message_reset_containers(sd_bus_message *m) {
- unsigned i;
+static struct bus_container *message_get_last_container(sd_bus_message *m) {
+ assert(m);
+
+ if (m->n_containers == 0)
+ return &m->root_container;
+
+ assert(m->containers);
+ return m->containers + m->n_containers - 1;
+}
+
+static void message_free_last_container(sd_bus_message *m) {
+ struct bus_container *c;
+ c = message_get_last_container(m);
+
+ free(c->signature);
+ free(c->peeked_signature);
+ free(c->offsets);
+
+ /* Move to previous container, but not if we are on root container */
+ if (m->n_containers > 0)
+ m->n_containers--;
+}
+
+static void message_reset_containers(sd_bus_message *m) {
assert(m);
- for (i = 0; i < m->n_containers; i++) {
- free(m->containers[i].signature);
- free(m->containers[i].offsets);
- }
+ while (m->n_containers > 0)
+ message_free_last_container(m);
m->containers = mfree(m->containers);
-
- m->n_containers = m->containers_allocated = 0;
+ m->containers_allocated = 0;
m->root_container.index = 0;
}
@@ -112,10 +129,8 @@ static sd_bus_message* message_free(sd_bus_message *m) {
free(m->iovec);
message_reset_containers(m);
- free(m->root_container.signature);
- free(m->root_container.offsets);
-
- free(m->root_container.peeked_signature);
+ assert(m->n_containers == 0);
+ message_free_last_container(m);
bus_creds_done(&m->creds);
return mfree(m);
@@ -210,7 +225,7 @@ static int message_append_field_string(
/* dbus1 doesn't allow strings over 32bit, let's enforce this
* globally, to not risk convertability */
l = strlen(s);
- if (l > (size_t) (uint32_t) -1)
+ if (l > UINT32_MAX)
return -EINVAL;
/* Signature "(yv)" where the variant contains "s" */
@@ -539,8 +554,7 @@ int bus_message_from_malloc(
m->n_iovec = 1;
m->iovec = m->iovec_fixed;
- m->iovec[0].iov_base = buffer;
- m->iovec[0].iov_len = length;
+ m->iovec[0] = IOVEC_MAKE(buffer, length);
r = bus_message_parse_fields(m);
if (r < 0)
@@ -876,30 +890,7 @@ int bus_message_new_synthetic_error(
return 0;
}
-_public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
-
- if (!m)
- return NULL;
-
- assert(m->n_ref > 0);
- m->n_ref++;
-
- return m;
-}
-
-_public_ sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
-
- if (!m)
- return NULL;
-
- assert(m->n_ref > 0);
- m->n_ref--;
-
- if (m->n_ref > 0)
- return NULL;
-
- return message_free(m);
-}
+DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_bus_message, sd_bus_message, message_free);
_public_ int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
assert_return(m, -EINVAL);
@@ -1113,16 +1104,6 @@ _public_ int sd_bus_message_set_allow_interactive_authorization(sd_bus_message *
return 0;
}
-static struct bus_container *message_get_container(sd_bus_message *m) {
- assert(m);
-
- if (m->n_containers == 0)
- return &m->root_container;
-
- assert(m->containers);
- return m->containers + m->n_containers - 1;
-}
-
struct bus_body_part *message_append_part(sd_bus_message *m) {
struct bus_body_part *part;
@@ -1213,7 +1194,7 @@ static int message_add_offset(sd_bus_message *m, size_t offset) {
/* Add offset to current container, unless this is the first
* item in it, which will have the 0 offset, which we can
* ignore. */
- c = message_get_container(m);
+ c = message_get_last_container(m);
if (!c->need_offsets)
return 0;
@@ -1385,7 +1366,7 @@ int message_append_basic(sd_bus_message *m, char type, const void *p, const void
assert_return(bus_type_is_basic(type), -EINVAL);
assert_return(!m->poisoned, -ESTALE);
- c = message_get_container(m);
+ c = message_get_last_container(m);
if (c->signature && c->signature[c->index]) {
/* Container signature is already set */
@@ -1578,7 +1559,7 @@ _public_ int sd_bus_message_append_string_space(
assert_return(!m->sealed, -EPERM);
assert_return(!m->poisoned, -ESTALE);
- c = message_get_container(m);
+ c = message_get_last_container(m);
if (c->signature && c->signature[c->index]) {
/* Container signature is already set */
@@ -1949,7 +1930,7 @@ _public_ int sd_bus_message_open_container(
char type,
const char *contents) {
- struct bus_container *c, *w;
+ struct bus_container *c;
uint32_t *array_size = NULL;
_cleanup_free_ char *signature = NULL;
size_t before, begin = 0;
@@ -1967,7 +1948,7 @@ _public_ int sd_bus_message_open_container(
return -ENOMEM;
}
- c = message_get_container(m);
+ c = message_get_last_container(m);
signature = strdup(contents);
if (!signature) {
@@ -1994,16 +1975,14 @@ _public_ int sd_bus_message_open_container(
return r;
/* OK, let's fill it in */
- w = m->containers + m->n_containers++;
- w->enclosing = type;
- w->signature = TAKE_PTR(signature);
- w->index = 0;
- w->array_size = array_size;
- w->before = before;
- w->begin = begin;
- w->n_offsets = w->offsets_allocated = 0;
- w->offsets = NULL;
- w->need_offsets = need_offsets;
+ m->containers[m->n_containers++] = (struct bus_container) {
+ .enclosing = type,
+ .signature = TAKE_PTR(signature),
+ .array_size = array_size,
+ .before = before,
+ .begin = begin,
+ .need_offsets = need_offsets,
+ };
return 0;
}
@@ -2194,7 +2173,7 @@ _public_ int sd_bus_message_close_container(sd_bus_message *m) {
assert_return(m->n_containers > 0, -EINVAL);
assert_return(!m->poisoned, -ESTALE);
- c = message_get_container(m);
+ c = message_get_last_container(m);
if (c->enclosing != SD_BUS_TYPE_ARRAY)
if (c->signature && c->signature[c->index] != 0)
@@ -2464,11 +2443,6 @@ _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
va_list ap;
int r;
- assert_return(m, -EINVAL);
- assert_return(types, -EINVAL);
- assert_return(!m->sealed, -EPERM);
- assert_return(!m->poisoned, -ESTALE);
-
va_start(ap, types);
r = sd_bus_message_appendv(m, types, ap);
va_end(ap);
@@ -2698,7 +2672,7 @@ _public_ int sd_bus_message_append_string_memfd(
if (size > (uint64_t) (uint32_t) -1)
return -EINVAL;
- c = message_get_container(m);
+ c = message_get_last_container(m);
if (c->signature && c->signature[c->index]) {
/* Container signature is already set */
@@ -3031,7 +3005,7 @@ static bool message_end_of_signature(sd_bus_message *m) {
assert(m);
- c = message_get_container(m);
+ c = message_get_last_container(m);
return !c->signature || c->signature[c->index] == 0;
}
@@ -3040,7 +3014,7 @@ static bool message_end_of_array(sd_bus_message *m, size_t index) {
assert(m);
- c = message_get_container(m);
+ c = message_get_last_container(m);
if (c->enclosing != SD_BUS_TYPE_ARRAY)
return false;
@@ -3135,6 +3109,7 @@ static int container_next_item(sd_bus_message *m, struct bus_container *c, size_
assert(alignment > 0);
*rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
+ assert(c->offsets[c->offset_index+1] >= *rindex);
c->item_size = c->offsets[c->offset_index+1] - *rindex;
} else {
@@ -3174,6 +3149,7 @@ static int container_next_item(sd_bus_message *m, struct bus_container *c, size_
assert(alignment > 0);
*rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
+ assert(c->offsets[c->offset_index+1] >= *rindex);
c->item_size = c->offsets[c->offset_index+1] - *rindex;
c->offset_index++;
@@ -3301,7 +3277,7 @@ _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
if (message_end_of_array(m, m->rindex))
return 0;
- c = message_get_container(m);
+ c = message_get_last_container(m);
if (c->signature[c->index] != type)
return -ENXIO;
@@ -3312,6 +3288,12 @@ _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) {
bool ok;
+ /* D-Bus spec: The marshalling formats for the string-like types all end
+ * with a single zero (NUL) byte, but that byte is not considered to be part
+ * of the text. */
+ if (c->item_size == 0)
+ return -EBADMSG;
+
r = message_peek_body(m, &rindex, 1, c->item_size, &q);
if (r < 0)
return r;
@@ -3406,6 +3388,10 @@ _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
return r;
l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
+ if (l == UINT32_MAX)
+ /* avoid overflow right below */
+ return -EBADMSG;
+
r = message_peek_body(m, &rindex, 1, l+1, &q);
if (r < 0)
return r;
@@ -3428,6 +3414,10 @@ _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
return r;
l = *(uint8_t*) q;
+ if (l == UINT8_MAX)
+ /* avoid overflow right below */
+ return -EBADMSG;
+
r = message_peek_body(m, &rindex, 1, l+1, &q);
if (r < 0)
return r;
@@ -3519,7 +3509,7 @@ static int bus_message_enter_array(
size_t rindex;
void *q;
- int r, alignment;
+ int r;
assert(m);
assert(c);
@@ -3545,6 +3535,7 @@ static int bus_message_enter_array(
if (!BUS_MESSAGE_IS_GVARIANT(m)) {
/* dbus1 */
+ int alignment;
r = message_peek_body(m, &rindex, 4, 4, &q);
if (r < 0)
@@ -3578,7 +3569,8 @@ static int bus_message_enter_array(
*n_offsets = 0;
} else {
- size_t where, p = 0, framing, sz;
+ size_t where, previous = 0, framing, sz;
+ int alignment;
unsigned i;
/* gvariant: variable length array */
@@ -3606,17 +3598,22 @@ static int bus_message_enter_array(
if (!*offsets)
return -ENOMEM;
+ alignment = bus_gvariant_get_alignment(c->signature);
+ assert(alignment > 0);
+
for (i = 0; i < *n_offsets; i++) {
- size_t x;
+ size_t x, start;
+
+ start = ALIGN_TO(previous, alignment);
x = bus_gvariant_read_word_le((uint8_t*) q + i * sz, sz);
if (x > c->item_size - sz)
return -EBADMSG;
- if (x < p)
+ if (x < start)
return -EBADMSG;
(*offsets)[i] = rindex + x;
- p = x;
+ previous = x;
}
*item_size = (*offsets)[0] - rindex;
@@ -3686,6 +3683,10 @@ static int bus_message_enter_variant(
return r;
l = *(uint8_t*) q;
+ if (l == UINT8_MAX)
+ /* avoid overflow right below */
+ return -EBADMSG;
+
r = message_peek_body(m, &rindex, 1, l+1, &q);
if (r < 0)
return r;
@@ -3714,7 +3715,7 @@ static int build_struct_offsets(
size_t *n_offsets) {
unsigned n_variable = 0, n_total = 0, v;
- size_t previous = 0, where;
+ size_t previous, where;
const char *p;
size_t sz;
void *q;
@@ -3793,6 +3794,7 @@ static int build_struct_offsets(
/* Second, loop again and build an offset table */
p = signature;
+ previous = m->rindex;
while (*p != 0) {
size_t n, offset;
int k;
@@ -3806,37 +3808,39 @@ static int build_struct_offsets(
memcpy(t, p, n);
t[n] = 0;
+ size_t align = bus_gvariant_get_alignment(t);
+ assert(align > 0);
+
+ /* The possible start of this member after including alignment */
+ size_t start = ALIGN_TO(previous, align);
+
k = bus_gvariant_get_size(t);
if (k < 0) {
size_t x;
- /* variable size */
+ /* Variable size */
if (v > 0) {
v--;
x = bus_gvariant_read_word_le((uint8_t*) q + v*sz, sz);
if (x >= size)
return -EBADMSG;
- if (m->rindex + x < previous)
- return -EBADMSG;
} else
- /* The last item's end
- * is determined from
- * the start of the
- * offset array */
+ /* The last item's end is determined
+ * from the start of the offset array */
x = size - (n_variable * sz);
offset = m->rindex + x;
-
- } else {
- size_t align;
-
- /* fixed size */
- align = bus_gvariant_get_alignment(t);
- assert(align > 0);
-
- offset = (*n_offsets == 0 ? m->rindex : ALIGN_TO((*offsets)[*n_offsets-1], align)) + k;
- }
+ if (offset < start)
+ return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
+ "For type %s with alignment %zu, message specifies offset %zu which is smaller than previous end %zu + alignment = %zu",
+ t, align,
+ offset,
+ previous,
+ start);
+ } else
+ /* Fixed size */
+ offset = start + k;
}
previous = (*offsets)[(*n_offsets)++] = offset;
@@ -3966,10 +3970,10 @@ static int bus_message_enter_dict_entry(
_public_ int sd_bus_message_enter_container(sd_bus_message *m,
char type,
const char *contents) {
- struct bus_container *c, *w;
+ struct bus_container *c;
uint32_t *array_size = NULL;
_cleanup_free_ char *signature = NULL;
- size_t before;
+ size_t before, end;
_cleanup_free_ size_t *offsets = NULL;
size_t n_offsets = 0, item_size = 0;
int r;
@@ -4025,7 +4029,7 @@ _public_ int sd_bus_message_enter_container(sd_bus_message *m,
if (message_end_of_array(m, m->rindex))
return 0;
- c = message_get_container(m);
+ c = message_get_last_container(m);
signature = strdup(contents);
if (!signature)
@@ -4048,28 +4052,26 @@ _public_ int sd_bus_message_enter_container(sd_bus_message *m,
return r;
/* OK, let's fill it in */
- w = m->containers + m->n_containers++;
- w->enclosing = type;
- w->signature = TAKE_PTR(signature);
- w->peeked_signature = NULL;
- w->index = 0;
-
- w->before = before;
- w->begin = m->rindex;
-
- /* Unary type has fixed size of 1, but virtual size of 0 */
if (BUS_MESSAGE_IS_GVARIANT(m) &&
type == SD_BUS_TYPE_STRUCT &&
isempty(signature))
- w->end = m->rindex + 0;
+ end = m->rindex + 0;
else
- w->end = m->rindex + c->item_size;
-
- w->array_size = array_size;
- w->item_size = item_size;
- w->offsets = TAKE_PTR(offsets);
- w->n_offsets = n_offsets;
- w->offset_index = 0;
+ end = m->rindex + c->item_size;
+
+ m->containers[m->n_containers++] = (struct bus_container) {
+ .enclosing = type,
+ .signature = TAKE_PTR(signature),
+
+ .before = before,
+ .begin = m->rindex,
+ /* Unary type has fixed size of 1, but virtual size of 0 */
+ .end = end,
+ .array_size = array_size,
+ .item_size = item_size,
+ .offsets = TAKE_PTR(offsets),
+ .n_offsets = n_offsets,
+ };
return 1;
}
@@ -4083,7 +4085,7 @@ _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
assert_return(m->sealed, -EPERM);
assert_return(m->n_containers > 0, -ENXIO);
- c = message_get_container(m);
+ c = message_get_last_container(m);
if (c->enclosing != SD_BUS_TYPE_ARRAY) {
if (c->signature && c->signature[c->index] != 0)
@@ -4102,13 +4104,9 @@ _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
return -EBUSY;
}
- free(c->signature);
- free(c->peeked_signature);
- free(c->offsets);
- m->n_containers--;
-
- c = message_get_container(m);
+ message_free_last_container(m);
+ c = message_get_last_container(m);
saved = c->index;
c->index = c->saved_index;
r = container_next_item(m, c, &m->rindex);
@@ -4126,19 +4124,16 @@ static void message_quit_container(sd_bus_message *m) {
assert(m->sealed);
assert(m->n_containers > 0);
- c = message_get_container(m);
-
/* Undo seeks */
+ c = message_get_last_container(m);
assert(m->rindex >= c->before);
m->rindex = c->before;
/* Free container */
- free(c->signature);
- free(c->offsets);
- m->n_containers--;
+ message_free_last_container(m);
/* Correct index of new top-level container */
- c = message_get_container(m);
+ c = message_get_last_container(m);
c->index = c->saved_index;
}
@@ -4155,7 +4150,7 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char
if (message_end_of_array(m, m->rindex))
goto eof;
- c = message_get_container(m);
+ c = message_get_last_container(m);
if (bus_type_is_basic(c->signature[c->index])) {
if (contents)
@@ -4169,20 +4164,20 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char
if (contents) {
size_t l;
- char *sig;
r = signature_element_length(c->signature+c->index+1, &l);
if (r < 0)
return r;
- assert(l >= 1);
+ /* signature_element_length does verification internally */
- sig = strndup(c->signature + c->index + 1, l);
- if (!sig)
+ /* The array element must not be empty */
+ assert(l >= 1);
+ if (free_and_strndup(&c->peeked_signature,
+ c->signature + c->index + 1, l) < 0)
return -ENOMEM;
- free(c->peeked_signature);
- *contents = c->peeked_signature = sig;
+ *contents = c->peeked_signature;
}
if (type)
@@ -4195,19 +4190,17 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char
if (contents) {
size_t l;
- char *sig;
r = signature_element_length(c->signature+c->index, &l);
if (r < 0)
return r;
- assert(l >= 2);
- sig = strndup(c->signature + c->index + 1, l - 2);
- if (!sig)
+ assert(l >= 3);
+ if (free_and_strndup(&c->peeked_signature,
+ c->signature + c->index + 1, l - 2) < 0)
return -ENOMEM;
- free(c->peeked_signature);
- *contents = c->peeked_signature = sig;
+ *contents = c->peeked_signature;
}
if (type)
@@ -4247,9 +4240,8 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char
if (k > c->item_size)
return -EBADMSG;
- free(c->peeked_signature);
- c->peeked_signature = strndup((char*) q + 1, k - 1);
- if (!c->peeked_signature)
+ if (free_and_strndup(&c->peeked_signature,
+ (char*) q + 1, k - 1) < 0)
return -ENOMEM;
if (!signature_is_valid(c->peeked_signature, true))
@@ -4265,6 +4257,10 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char
return r;
l = *(uint8_t*) q;
+ if (l == UINT8_MAX)
+ /* avoid overflow right below */
+ return -EBADMSG;
+
r = message_peek_body(m, &rindex, 1, l+1, &q);
if (r < 0)
return r;
@@ -4302,11 +4298,10 @@ _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
message_reset_containers(m);
m->rindex = 0;
- c = message_get_container(m);
+ c = message_get_last_container(m);
} else {
- c = message_get_container(m);
+ c = message_get_last_container(m);
- c->offset_index = 0;
c->index = 0;
m->rindex = c->begin;
}
@@ -4317,7 +4312,7 @@ _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
return !isempty(c->signature);
}
-static int message_read_ap(
+_public_ int sd_bus_message_readv(
sd_bus_message *m,
const char *types,
va_list ap) {
@@ -4328,7 +4323,9 @@ static int message_read_ap(
unsigned n_loop = 0;
int r;
- assert(m);
+ assert_return(m, -EINVAL);
+ assert_return(m->sealed, -EPERM);
+ assert_return(types, -EINVAL);
if (isempty(types))
return 0;
@@ -4519,12 +4516,8 @@ _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
va_list ap;
int r;
- assert_return(m, -EINVAL);
- assert_return(m->sealed, -EPERM);
- assert_return(types, -EINVAL);
-
va_start(ap, types);
- r = message_read_ap(m, types, ap);
+ r = sd_bus_message_readv(m, types, ap);
va_end(ap);
return r;
@@ -4547,7 +4540,7 @@ _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
if (message_end_of_array(m, m->rindex))
return 0;
- c = message_get_container(m);
+ c = message_get_last_container(m);
r = signature_element_length(c->signature + c->index, &l);
if (r < 0)
@@ -4713,7 +4706,7 @@ _public_ int sd_bus_message_read_array(
if (r <= 0)
return r;
- c = message_get_container(m);
+ c = message_get_last_container(m);
if (BUS_MESSAGE_IS_GVARIANT(m)) {
align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
@@ -4850,6 +4843,10 @@ static int message_peek_field_string(
if (r < 0)
return r;
+ if (l == UINT32_MAX)
+ /* avoid overflow right below */
+ return -EBADMSG;
+
r = message_peek_fields(m, ri, 1, l+1, &q);
if (r < 0)
return r;
@@ -4901,6 +4898,10 @@ static int message_peek_field_signature(
return r;
l = *(uint8_t*) q;
+ if (l == UINT8_MAX)
+ /* avoid overflow right below */
+ return -EBADMSG;
+
r = message_peek_fields(m, ri, 1, l+1, &q);
if (r < 0)
return r;
@@ -4982,18 +4983,18 @@ static int message_skip_fields(
} else if (t == SD_BUS_TYPE_ARRAY) {
- r = signature_element_length(*signature+1, &l);
+ r = signature_element_length(*signature + 1, &l);
if (r < 0)
return r;
assert(l >= 1);
{
- char sig[l-1], *s;
+ char sig[l + 1], *s = sig;
uint32_t nas;
int alignment;
- strncpy(sig, *signature + 1, l-1);
- s = sig;
+ strncpy(sig, *signature + 1, l);
+ sig[l] = '\0';
alignment = bus_type_get_alignment(sig[0]);
if (alignment < 0)
@@ -5037,9 +5038,9 @@ static int message_skip_fields(
assert(l >= 2);
{
- char sig[l-1], *s;
- strncpy(sig, *signature + 1, l-1);
- s = sig;
+ char sig[l + 1], *s = sig;
+ strncpy(sig, *signature + 1, l);
+ sig[l] = '\0';
r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
if (r < 0)
@@ -5048,7 +5049,7 @@ static int message_skip_fields(
*signature += l;
} else
- return -EINVAL;
+ return -EBADMSG;
}
}
@@ -5078,26 +5079,25 @@ int bus_message_parse_fields(sd_bus_message *m) {
return -EBADMSG;
if (*p == 0) {
+ char *k;
size_t l;
- char *c;
/* We found the beginning of the signature
* string, yay! We require the body to be a
* structure, so verify it and then strip the
* opening/closing brackets. */
- l = ((char*) m->footer + m->footer_accessible) - p - (1 + sz);
+ l = (char*) m->footer + m->footer_accessible - p - (1 + sz);
if (l < 2 ||
p[1] != SD_BUS_TYPE_STRUCT_BEGIN ||
p[1 + l - 1] != SD_BUS_TYPE_STRUCT_END)
return -EBADMSG;
- c = strndup(p + 1 + 1, l - 2);
- if (!c)
+ k = memdup_suffix0(p + 1 + 1, l - 2);
+ if (!k)
return -ENOMEM;
- free(m->root_container.signature);
- m->root_container.signature = c;
+ free_and_replace(m->root_container.signature, k);
break;
}
@@ -5419,6 +5419,8 @@ int bus_message_parse_fields(sd_bus_message *m) {
&m->root_container.item_size,
&m->root_container.offsets,
&m->root_container.n_offsets);
+ if (r == -EINVAL)
+ return -EBADMSG;
if (r < 0)
return r;
}
@@ -5433,6 +5435,7 @@ int bus_message_parse_fields(sd_bus_message *m) {
_public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
assert_return(m, -EINVAL);
assert_return(destination, -EINVAL);
+ assert_return(service_name_is_valid(destination), -EINVAL);
assert_return(!m->sealed, -EPERM);
assert_return(!m->destination, -EEXIST);
@@ -5442,6 +5445,7 @@ _public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *desti
_public_ int sd_bus_message_set_sender(sd_bus_message *m, const char *sender) {
assert_return(m, -EINVAL);
assert_return(sender, -EINVAL);
+ assert_return(service_name_is_valid(sender), -EINVAL);
assert_return(!m->sealed, -EPERM);
assert_return(!m->sender, -EEXIST);
@@ -5612,7 +5616,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);
+ c = complete ? &m->root_container : message_get_last_container(m);
return strempty(c->signature);
}
@@ -5809,8 +5813,11 @@ int bus_message_remarshal(sd_bus *bus, sd_bus_message **m) {
return r;
timeout = (*m)->timeout;
- if (timeout == 0 && !((*m)->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED))
- timeout = BUS_DEFAULT_TIMEOUT;
+ if (timeout == 0 && !((*m)->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)) {
+ r = sd_bus_get_method_call_timeout(bus, &timeout);
+ if (r < 0)
+ return r;
+ }
r = sd_bus_message_seal(n, BUS_MESSAGE_COOKIE(*m), timeout);
if (r < 0)
@@ -5822,16 +5829,6 @@ int bus_message_remarshal(sd_bus *bus, sd_bus_message **m) {
return 0;
}
-int bus_message_append_sender(sd_bus_message *m, const char *sender) {
- assert(m);
- assert(sender);
-
- assert_return(!m->sealed, -EPERM);
- assert_return(!m->sender, -EPERM);
-
- return message_append_field_string(m, BUS_MESSAGE_HEADER_SENDER, SD_BUS_TYPE_STRING, sender, &m->sender);
-}
-
_public_ int sd_bus_message_get_priority(sd_bus_message *m, int64_t *priority) {
assert_return(m, -EINVAL);
assert_return(priority, -EINVAL);