summaryrefslogtreecommitdiff
path: root/src/libelogind
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2018-07-09 07:03:01 +0200
committerSven Eden <sven.eden@prydeworx.com>2018-10-29 10:18:27 +0100
commit081232081ccb96d2361834625caba4d3d2341437 (patch)
tree7f115420e77b9bb903a9f0e640d39020865a87e2 /src/libelogind
parent4ac4caa2cf2ee617c1b9b53246aa07cb8bf54154 (diff)
Introduce free_and_strndup and use it in bus-message.c
v2: fix error in free_and_strndup() When the orignal and copied message were the same, but shorter than specified length l, memory read past the end of the buffer would be performed. A test case is included: a string that had an embedded NUL ("q\0") is used to replace "q". v3: Fix one more bug in free_and_strndup and add tests. v4: Some style fixed based on review, one more use of free_and_replace, and make the tests more comprehensive. (cherry picked from commit 7f546026abbdc56c453a577e52d57159458c3e9c)
Diffstat (limited to 'src/libelogind')
-rw-r--r--src/libelogind/sd-bus/bus-message.c34
1 files changed, 13 insertions, 21 deletions
diff --git a/src/libelogind/sd-bus/bus-message.c b/src/libelogind/sd-bus/bus-message.c
index 906f19c76..0d21be0ae 100644
--- a/src/libelogind/sd-bus/bus-message.c
+++ b/src/libelogind/sd-bus/bus-message.c
@@ -4169,20 +4169,19 @@ _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)
+ 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 +4194,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)
+ 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 +4244,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))
@@ -5079,25 +5075,21 @@ int bus_message_parse_fields(sd_bus_message *m) {
if (*p == 0) {
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)
+ if (free_and_strndup(&m->root_container.signature,
+ p + 1 + 1, l - 2) < 0)
return -ENOMEM;
-
- free(m->root_container.signature);
- m->root_container.signature = c;
break;
}