chiark
/
gitweb
/
~ianmdlvl
/
elogind.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
bus: validate the entire header more closely
[elogind.git]
/
src
/
libsystemd-bus
/
bus-message.c
diff --git
a/src/libsystemd-bus/bus-message.c
b/src/libsystemd-bus/bus-message.c
index c385ef5ed05b1e39387e6e447677a827c6b2a25c..a22962559de8ed94c298443981c938e70da536ed 100644
(file)
--- a/
src/libsystemd-bus/bus-message.c
+++ b/
src/libsystemd-bus/bus-message.c
@@
-403,6
+403,8
@@
static int message_new_reply(
if (!call)
return -EINVAL;
if (!call)
return -EINVAL;
+ if (!call->sealed)
+ return -EPERM;
if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
return -EINVAL;
if (!m)
if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
return -EINVAL;
if (!m)
@@
-766,11
+768,27
@@
int message_append_basic(sd_bus_message *m, char type, const void *p, const void
case SD_BUS_TYPE_STRING:
case SD_BUS_TYPE_OBJECT_PATH:
case SD_BUS_TYPE_STRING:
case SD_BUS_TYPE_OBJECT_PATH:
+
+ if (!p) {
+ if (e)
+ c->signature[c->index] = 0;
+
+ return -EINVAL;
+ }
+
align = 4;
sz = 4 + strlen(p) + 1;
break;
case SD_BUS_TYPE_SIGNATURE:
align = 4;
sz = 4 + strlen(p) + 1;
break;
case SD_BUS_TYPE_SIGNATURE:
+
+ if (!p) {
+ if (e)
+ c->signature[c->index] = 0;
+
+ return -EINVAL;
+ }
+
align = 1;
sz = 1 + strlen(p) + 1;
break;
align = 1;
sz = 1 + strlen(p) + 1;
break;
@@
-1356,8
+1374,7
@@
static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, si
return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
}
return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
}
-static bool validate_string(const char *s, size_t l) {
- assert(s);
+static bool validate_nul(const char *s, size_t l) {
/* Check for NUL chars in the string */
if (memchr(s, 0, l))
/* Check for NUL chars in the string */
if (memchr(s, 0, l))
@@
-1367,6
+1384,14
@@
static bool validate_string(const char *s, size_t l) {
if (s[l] != 0)
return false;
if (s[l] != 0)
return false;
+ return true;
+}
+
+static bool validate_string(const char *s, size_t l) {
+
+ if (!validate_nul(s, l))
+ return false;
+
/* Check if valid UTF8 */
if (!utf8_is_valid(s))
return false;
/* Check if valid UTF8 */
if (!utf8_is_valid(s))
return false;
@@
-1375,12
+1400,8
@@
static bool validate_string(const char *s, size_t l) {
}
static bool validate_signature(const char *s, size_t l) {
}
static bool validate_signature(const char *s, size_t l) {
- /* Check for NUL chars in the signature */
- if (memchr(s, 0, l))
- return false;
- /* Check for NUL termination */
- if (s[l] != 0)
+ if (!validate_nul(s, l))
return false;
/* Check if valid signature */
return false;
/* Check if valid signature */
@@
-1390,6
+1411,17
@@
static bool validate_signature(const char *s, size_t l) {
return true;
}
return true;
}
+static bool validate_object_path(const char *s, size_t l) {
+
+ if (!validate_nul(s, l))
+ return false;
+
+ if (!object_path_is_valid(s))
+ return false;
+
+ return true;
+}
+
int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
struct bus_container *c;
int r;
int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
struct bus_container *c;
int r;
@@
-1429,8
+1461,13
@@
int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
if (r == 0)
return -EBADMSG;
if (r == 0)
return -EBADMSG;
- if (!validate_string(q, l))
- return -EBADMSG;
+ if (type == SD_BUS_TYPE_OBJECT_PATH) {
+ if (!validate_object_path(q, l))
+ return -EBADMSG;
+ } else {
+ if (!validate_string(q, l))
+ return -EBADMSG;
+ }
m->rindex = rindex;
*(const char**) p = q;
m->rindex = rindex;
*(const char**) p = q;
@@
-1547,7
+1584,7
@@
static int bus_message_enter_array(
if (r <= 0)
return r;
if (r <= 0)
return r;
- if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) >
67108864
)
+ if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) >
BUS_ARRAY_MAX_SIZE
)
return -EBADMSG;
r = message_peek_body(m, &rindex, alignment, 0, NULL);
return -EBADMSG;
r = message_peek_body(m, &rindex, alignment, 0, NULL);
@@
-2086,6
+2123,7
@@
static int message_peek_fields(
static int message_peek_field_string(
sd_bus_message *m,
static int message_peek_field_string(
sd_bus_message *m,
+ bool (*validate)(const char *p),
size_t *ri,
const char **ret) {
size_t *ri,
const char **ret) {
@@
-2105,8
+2143,16
@@
static int message_peek_field_string(
if (r < 0)
return r;
if (r < 0)
return r;
- if (!validate_string(q, l))
- return -EBADMSG;
+ if (validate) {
+ if (!validate_nul(q, l))
+ return -EBADMSG;
+
+ if (!validate(q))
+ return -EBADMSG;
+ } else {
+ if (!validate_string(q, l))
+ return -EBADMSG;
+ }
if (ret)
*ret = q;
if (ret)
*ret = q;
@@
-2193,10
+2239,17
@@
static int message_skip_fields(
if (!t)
return 0;
if (!t)
return 0;
- if (t == SD_BUS_TYPE_STRING ||
- t == SD_BUS_TYPE_OBJECT_PATH) {
+ if (t == SD_BUS_TYPE_STRING) {
- r = message_peek_field_string(m, ri, NULL);
+ r = message_peek_field_string(m, NULL, ri, NULL);
+ if (r < 0)
+ return r;
+
+ (*signature)++;
+
+ } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
+
+ r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
if (r < 0)
return r;
if (r < 0)
return r;
@@
-2213,8
+2266,8
@@
static int message_skip_fields(
} else if (bus_type_is_basic(t)) {
size_t align, k;
} else if (bus_type_is_basic(t)) {
size_t align, k;
- align = bus_type_get_alignment(
align
);
- k = bus_type_get_size(
align
);
+ align = bus_type_get_alignment(
t
);
+ k = bus_type_get_size(
t
);
r = message_peek_fields(m, ri, align, k, NULL);
if (r < 0)
r = message_peek_fields(m, ri, align, k, NULL);
if (r < 0)
@@
-2246,7
+2299,7
@@
static int message_skip_fields(
return r;
nas = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
return r;
nas = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
- if (nas >
67108864
)
+ if (nas >
BUS_ARRAY_MAX_SIZE
)
return -EBADMSG;
r = message_peek_fields(m, ri, alignment, 0, NULL);
return -EBADMSG;
r = message_peek_fields(m, ri, alignment, 0, NULL);
@@
-2323,42
+2376,42
@@
static int message_parse_fields(sd_bus_message *m) {
if (!streq(signature, "o"))
return -EBADMSG;
if (!streq(signature, "o"))
return -EBADMSG;
- r = message_peek_field_string(m, &ri, &m->path);
+ r = message_peek_field_string(m,
object_path_is_valid,
&ri, &m->path);
break;
case SD_BUS_MESSAGE_HEADER_INTERFACE:
if (!streq(signature, "s"))
return -EBADMSG;
break;
case SD_BUS_MESSAGE_HEADER_INTERFACE:
if (!streq(signature, "s"))
return -EBADMSG;
- r = message_peek_field_string(m, &ri, &m->interface);
+ r = message_peek_field_string(m,
interface_name_is_valid,
&ri, &m->interface);
break;
case SD_BUS_MESSAGE_HEADER_MEMBER:
if (!streq(signature, "s"))
return -EBADMSG;
break;
case SD_BUS_MESSAGE_HEADER_MEMBER:
if (!streq(signature, "s"))
return -EBADMSG;
- r = message_peek_field_string(m, &ri, &m->member);
+ r = message_peek_field_string(m,
member_name_is_valid,
&ri, &m->member);
break;
case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
if (!streq(signature, "s"))
return -EBADMSG;
break;
case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
if (!streq(signature, "s"))
return -EBADMSG;
- r = message_peek_field_string(m, &ri, &m->error.name);
+ r = message_peek_field_string(m,
error_name_is_valid,
&ri, &m->error.name);
break;
case SD_BUS_MESSAGE_HEADER_DESTINATION:
if (!streq(signature, "s"))
return -EBADMSG;
break;
case SD_BUS_MESSAGE_HEADER_DESTINATION:
if (!streq(signature, "s"))
return -EBADMSG;
- r = message_peek_field_string(m, &ri, &m->destination);
+ r = message_peek_field_string(m,
service_name_is_valid,
&ri, &m->destination);
break;
case SD_BUS_MESSAGE_HEADER_SENDER:
if (!streq(signature, "s"))
return -EBADMSG;
break;
case SD_BUS_MESSAGE_HEADER_SENDER:
if (!streq(signature, "s"))
return -EBADMSG;
- r = message_peek_field_string(m, &ri, &m->sender);
+ r = message_peek_field_string(m,
service_name_is_valid,
&ri, &m->sender);
break;
break;
@@
-2389,6
+2442,12
@@
static int message_parse_fields(sd_bus_message *m) {
return -EBADMSG;
r = message_peek_field_uint32(m, &ri, &m->reply_serial);
return -EBADMSG;
r = message_peek_field_uint32(m, &ri, &m->reply_serial);
+ if (r < 0)
+ return r;
+
+ if (m->reply_serial == 0)
+ return -EBADMSG;
+
break;
default:
break;
default:
@@
-2441,14
+2500,17
@@
static void setup_iovec(sd_bus_message *m) {
assert(m->sealed);
m->n_iovec = 0;
assert(m->sealed);
m->n_iovec = 0;
+ m->size = 0;
m->iovec[m->n_iovec].iov_base = m->header;
m->iovec[m->n_iovec].iov_len = sizeof(*m->header);
m->iovec[m->n_iovec].iov_base = m->header;
m->iovec[m->n_iovec].iov_len = sizeof(*m->header);
+ m->size += m->iovec[m->n_iovec].iov_len;
m->n_iovec++;
if (m->fields) {
m->iovec[m->n_iovec].iov_base = m->fields;
m->iovec[m->n_iovec].iov_len = m->header->fields_size;
m->n_iovec++;
if (m->fields) {
m->iovec[m->n_iovec].iov_base = m->fields;
m->iovec[m->n_iovec].iov_len = m->header->fields_size;
+ m->size += m->iovec[m->n_iovec].iov_len;
m->n_iovec++;
if (m->header->fields_size % 8 != 0) {
m->n_iovec++;
if (m->header->fields_size % 8 != 0) {
@@
-2456,6
+2518,7
@@
static void setup_iovec(sd_bus_message *m) {
m->iovec[m->n_iovec].iov_base = (void*) padding;
m->iovec[m->n_iovec].iov_len = 8 - m->header->fields_size % 8;
m->iovec[m->n_iovec].iov_base = (void*) padding;
m->iovec[m->n_iovec].iov_len = 8 - m->header->fields_size % 8;
+ m->size += m->iovec[m->n_iovec].iov_len;
m->n_iovec++;
}
}
m->n_iovec++;
}
}
@@
-2463,6
+2526,7
@@
static void setup_iovec(sd_bus_message *m) {
if (m->body) {
m->iovec[m->n_iovec].iov_base = m->body;
m->iovec[m->n_iovec].iov_len = m->header->body_size;
if (m->body) {
m->iovec[m->n_iovec].iov_base = m->body;
m->iovec[m->n_iovec].iov_len = m->header->body_size;
+ m->size += m->iovec[m->n_iovec].iov_len;
m->n_iovec++;
}
}
m->n_iovec++;
}
}