summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2022-05-26 21:23:10 +0200
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2022-05-28 10:06:14 +0200
commit89b6a3f13e5f3b8a375dc82cb2a1c2c204a5067e (patch)
tree48dc01dc9478ee164c6a5ab22c090ddff66ba7aa /src
parentMerge pull request #23518 from enr0n/sd-hwdb-from-path (diff)
downloadsystemd-89b6a3f13e5f3b8a375dc82cb2a1c2c204a5067e.tar.xz
systemd-89b6a3f13e5f3b8a375dc82cb2a1c2c204a5067e.zip
sd-bus: fix buffer overflow
Fixes #23486.
Diffstat (limited to 'src')
-rw-r--r--src/libsystemd/sd-bus/bus-message.c30
1 files changed, 23 insertions, 7 deletions
diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
index b77372c3a0..026ec101e3 100644
--- a/src/libsystemd/sd-bus/bus-message.c
+++ b/src/libsystemd/sd-bus/bus-message.c
@@ -428,7 +428,7 @@ int bus_message_from_header(
_cleanup_free_ sd_bus_message *m = NULL;
struct bus_header *h;
- size_t a, label_sz;
+ size_t a, label_sz = 0; /* avoid false maybe-uninitialized warning */
assert(bus);
assert(header || header_accessible <= 0);
@@ -506,7 +506,10 @@ int bus_message_from_header(
m->fields_size = BUS_MESSAGE_BSWAP32(m, h->dbus1.fields_size);
m->body_size = BUS_MESSAGE_BSWAP32(m, h->dbus1.body_size);
- if (sizeof(struct bus_header) + ALIGN8(m->fields_size) + m->body_size != message_size)
+ assert(message_size >= sizeof(struct bus_header));
+ if (m->fields_size > message_size - sizeof(struct bus_header) ||
+ ALIGN8(m->fields_size) > message_size - sizeof(struct bus_header) ||
+ m->body_size != message_size - sizeof(struct bus_header) - ALIGN8(m->fields_size))
return -EBADMSG;
}
@@ -3061,15 +3064,21 @@ void bus_body_part_unmap(struct bus_body_part *part) {
return;
}
-static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
+static int buffer_peek(const void *p, size_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
size_t k, start, end;
assert(rindex);
assert(align > 0);
- start = ALIGN_TO((size_t) *rindex, align);
- end = start + nbytes;
+ start = ALIGN_TO(*rindex, align);
+ if (start > sz)
+ return -EBADMSG;
+
+ /* Avoid overflow below */
+ if (nbytes > SIZE_MAX - start)
+ return -EBADMSG;
+ end = start + nbytes;
if (end > sz)
return -EBADMSG;
@@ -3272,10 +3281,17 @@ static int message_peek_body(
assert(rindex);
assert(align > 0);
- start = ALIGN_TO((size_t) *rindex, align);
+ start = ALIGN_TO(*rindex, align);
+ if (start > m->user_body_size)
+ return -EBADMSG;
+
padding = start - *rindex;
- end = start + nbytes;
+ /* Avoid overflow below */
+ if (nbytes > SIZE_MAX - start)
+ return -EBADMSG;
+
+ end = start + nbytes;
if (end > m->user_body_size)
return -EBADMSG;