|
|
4bff0a |
From a2da2b45ac05ef91074e90097115e8c734ca0f64 Mon Sep 17 00:00:00 2001
|
|
|
4bff0a |
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
|
|
4bff0a |
Date: Mon, 9 Jul 2018 10:52:51 +0200
|
|
|
4bff0a |
Subject: [PATCH] bus-message: avoid an infinite loop on empty structures
|
|
|
4bff0a |
|
|
|
4bff0a |
The alternative would be to treat gvariant and !gvariant messages differently.
|
|
|
4bff0a |
But this is a problem because we check signatures is variuos places before we
|
|
|
4bff0a |
have an actual message, for example in sd_bus_add_object_vtable(). It seems
|
|
|
4bff0a |
better to treat things consistent (i.e. follow the lowest common denominator)
|
|
|
4bff0a |
and disallow empty structures everywhere.
|
|
|
4bff0a |
|
|
|
4bff0a |
(cherry picked from commit ec6bda56cbca9509b1abde1122645630caca877c)
|
|
|
4bff0a |
|
|
|
4bff0a |
Resolves: #1696224
|
|
|
4bff0a |
---
|
|
|
4bff0a |
src/libsystemd/sd-bus/bus-message.c | 3 ++-
|
|
|
4bff0a |
src/libsystemd/sd-bus/bus-signature.c | 6 ++++++
|
|
|
4bff0a |
src/libsystemd/sd-bus/test-bus-gvariant.c | 6 +++---
|
|
|
4bff0a |
src/libsystemd/sd-bus/test-bus-marshal.c | 6 +++---
|
|
|
4bff0a |
src/libsystemd/sd-bus/test-bus-signature.c | 8 ++++----
|
|
|
4bff0a |
...crash-26bba7182dedc8848939931d9fcefcb7922f2e56 | Bin 0 -> 157 bytes
|
|
|
4bff0a |
...meout-08ee8f6446a4064db064e8e0b3d220147f7d0b5b | Bin 0 -> 534 bytes
|
|
|
4bff0a |
7 files changed, 18 insertions(+), 11 deletions(-)
|
|
|
4bff0a |
create mode 100644 test/fuzz/fuzz-bus-message/crash-26bba7182dedc8848939931d9fcefcb7922f2e56
|
|
|
4bff0a |
create mode 100644 test/fuzz/fuzz-bus-message/timeout-08ee8f6446a4064db064e8e0b3d220147f7d0b5b
|
|
|
4bff0a |
|
|
|
4bff0a |
diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
|
|
|
4bff0a |
index 7f87d018fb..1d06fcb80e 100644
|
|
|
4bff0a |
--- a/src/libsystemd/sd-bus/bus-message.c
|
|
|
4bff0a |
+++ b/src/libsystemd/sd-bus/bus-message.c
|
|
|
4bff0a |
@@ -4178,6 +4178,7 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char
|
|
|
4bff0a |
|
|
|
4bff0a |
/* signature_element_length does verification internally */
|
|
|
4bff0a |
|
|
|
4bff0a |
+ /* The array element must not be empty */
|
|
|
4bff0a |
assert(l >= 1);
|
|
|
4bff0a |
if (free_and_strndup(&c->peeked_signature,
|
|
|
4bff0a |
c->signature + c->index + 1, l) < 0)
|
|
|
4bff0a |
@@ -4201,7 +4202,7 @@ _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char
|
|
|
4bff0a |
if (r < 0)
|
|
|
4bff0a |
return r;
|
|
|
4bff0a |
|
|
|
4bff0a |
- assert(l >= 2);
|
|
|
4bff0a |
+ assert(l >= 3);
|
|
|
4bff0a |
if (free_and_strndup(&c->peeked_signature,
|
|
|
4bff0a |
c->signature + c->index + 1, l - 2) < 0)
|
|
|
4bff0a |
return -ENOMEM;
|
|
|
4bff0a |
diff --git a/src/libsystemd/sd-bus/bus-signature.c b/src/libsystemd/sd-bus/bus-signature.c
|
|
|
4bff0a |
index 18c91e8707..1ca37cbb5a 100644
|
|
|
4bff0a |
--- a/src/libsystemd/sd-bus/bus-signature.c
|
|
|
4bff0a |
+++ b/src/libsystemd/sd-bus/bus-signature.c
|
|
|
4bff0a |
@@ -58,6 +58,12 @@ static int signature_element_length_internal(
|
|
|
4bff0a |
p += t;
|
|
|
4bff0a |
}
|
|
|
4bff0a |
|
|
|
4bff0a |
+ if (p - s < 2)
|
|
|
4bff0a |
+ /* D-Bus spec: Empty structures are not allowed; there
|
|
|
4bff0a |
+ * must be at least one type code between the parentheses.
|
|
|
4bff0a |
+ */
|
|
|
4bff0a |
+ return -EINVAL;
|
|
|
4bff0a |
+
|
|
|
4bff0a |
*l = p - s + 1;
|
|
|
4bff0a |
return 0;
|
|
|
4bff0a |
}
|
|
|
4bff0a |
diff --git a/src/libsystemd/sd-bus/test-bus-gvariant.c b/src/libsystemd/sd-bus/test-bus-gvariant.c
|
|
|
4bff0a |
index 75804f3458..e606970a3a 100644
|
|
|
4bff0a |
--- a/src/libsystemd/sd-bus/test-bus-gvariant.c
|
|
|
4bff0a |
+++ b/src/libsystemd/sd-bus/test-bus-gvariant.c
|
|
|
4bff0a |
@@ -19,7 +19,7 @@
|
|
|
4bff0a |
|
|
|
4bff0a |
static void test_bus_gvariant_is_fixed_size(void) {
|
|
|
4bff0a |
assert_se(bus_gvariant_is_fixed_size("") > 0);
|
|
|
4bff0a |
- assert_se(bus_gvariant_is_fixed_size("()") > 0);
|
|
|
4bff0a |
+ assert_se(bus_gvariant_is_fixed_size("()") == -EINVAL);
|
|
|
4bff0a |
assert_se(bus_gvariant_is_fixed_size("y") > 0);
|
|
|
4bff0a |
assert_se(bus_gvariant_is_fixed_size("u") > 0);
|
|
|
4bff0a |
assert_se(bus_gvariant_is_fixed_size("b") > 0);
|
|
|
4bff0a |
@@ -44,7 +44,7 @@ static void test_bus_gvariant_is_fixed_size(void) {
|
|
|
4bff0a |
|
|
|
4bff0a |
static void test_bus_gvariant_get_size(void) {
|
|
|
4bff0a |
assert_se(bus_gvariant_get_size("") == 0);
|
|
|
4bff0a |
- assert_se(bus_gvariant_get_size("()") == 1);
|
|
|
4bff0a |
+ assert_se(bus_gvariant_get_size("()") == -EINVAL);
|
|
|
4bff0a |
assert_se(bus_gvariant_get_size("y") == 1);
|
|
|
4bff0a |
assert_se(bus_gvariant_get_size("u") == 4);
|
|
|
4bff0a |
assert_se(bus_gvariant_get_size("b") == 1);
|
|
|
4bff0a |
@@ -76,7 +76,7 @@ static void test_bus_gvariant_get_size(void) {
|
|
|
4bff0a |
|
|
|
4bff0a |
static void test_bus_gvariant_get_alignment(void) {
|
|
|
4bff0a |
assert_se(bus_gvariant_get_alignment("") == 1);
|
|
|
4bff0a |
- assert_se(bus_gvariant_get_alignment("()") == 1);
|
|
|
4bff0a |
+ assert_se(bus_gvariant_get_alignment("()") == -EINVAL);
|
|
|
4bff0a |
assert_se(bus_gvariant_get_alignment("y") == 1);
|
|
|
4bff0a |
assert_se(bus_gvariant_get_alignment("b") == 1);
|
|
|
4bff0a |
assert_se(bus_gvariant_get_alignment("u") == 4);
|
|
|
4bff0a |
diff --git a/src/libsystemd/sd-bus/test-bus-marshal.c b/src/libsystemd/sd-bus/test-bus-marshal.c
|
|
|
4bff0a |
index f007168ca6..1743b1b491 100644
|
|
|
4bff0a |
--- a/src/libsystemd/sd-bus/test-bus-marshal.c
|
|
|
4bff0a |
+++ b/src/libsystemd/sd-bus/test-bus-marshal.c
|
|
|
4bff0a |
@@ -151,7 +151,7 @@ int main(int argc, char *argv[]) {
|
|
|
4bff0a |
assert_se(r >= 0);
|
|
|
4bff0a |
|
|
|
4bff0a |
r = sd_bus_message_append(m, "()");
|
|
|
4bff0a |
- assert_se(r >= 0);
|
|
|
4bff0a |
+ assert_se(r == -EINVAL);
|
|
|
4bff0a |
|
|
|
4bff0a |
r = sd_bus_message_append(m, "ba(ss)", 255, 3, "aaa", "1", "bbb", "2", "ccc", "3");
|
|
|
4bff0a |
assert_se(r >= 0);
|
|
|
4bff0a |
@@ -293,7 +293,7 @@ int main(int argc, char *argv[]) {
|
|
|
4bff0a |
assert_se(v == 10);
|
|
|
4bff0a |
|
|
|
4bff0a |
r = sd_bus_message_read(m, "()");
|
|
|
4bff0a |
- assert_se(r > 0);
|
|
|
4bff0a |
+ assert_se(r < 0);
|
|
|
4bff0a |
|
|
|
4bff0a |
r = sd_bus_message_read(m, "ba(ss)", &boolean, 3, &x, &y, &a, &b, &c, &d);
|
|
|
4bff0a |
assert_se(r > 0);
|
|
|
4bff0a |
@@ -374,7 +374,7 @@ int main(int argc, char *argv[]) {
|
|
|
4bff0a |
|
|
|
4bff0a |
assert_se(sd_bus_message_verify_type(m, 'a', "{yv}") > 0);
|
|
|
4bff0a |
|
|
|
4bff0a |
- r = sd_bus_message_skip(m, "a{yv}y(ty)y(yt)y()");
|
|
|
4bff0a |
+ r = sd_bus_message_skip(m, "a{yv}y(ty)y(yt)y");
|
|
|
4bff0a |
assert_se(r >= 0);
|
|
|
4bff0a |
|
|
|
4bff0a |
assert_se(sd_bus_message_verify_type(m, 'b', NULL) > 0);
|
|
|
4bff0a |
diff --git a/src/libsystemd/sd-bus/test-bus-signature.c b/src/libsystemd/sd-bus/test-bus-signature.c
|
|
|
4bff0a |
index 1ba1909198..a716cd1b35 100644
|
|
|
4bff0a |
--- a/src/libsystemd/sd-bus/test-bus-signature.c
|
|
|
4bff0a |
+++ b/src/libsystemd/sd-bus/test-bus-signature.c
|
|
|
4bff0a |
@@ -16,9 +16,9 @@ int main(int argc, char *argv[]) {
|
|
|
4bff0a |
assert_se(signature_is_single("v", false));
|
|
|
4bff0a |
assert_se(signature_is_single("as", false));
|
|
|
4bff0a |
assert_se(signature_is_single("(ss)", false));
|
|
|
4bff0a |
- assert_se(signature_is_single("()", false));
|
|
|
4bff0a |
- assert_se(signature_is_single("(()()()()())", false));
|
|
|
4bff0a |
- assert_se(signature_is_single("(((())))", false));
|
|
|
4bff0a |
+ assert_se(!signature_is_single("()", false));
|
|
|
4bff0a |
+ assert_se(!signature_is_single("(()()()()())", false));
|
|
|
4bff0a |
+ assert_se(!signature_is_single("(((())))", false));
|
|
|
4bff0a |
assert_se(signature_is_single("((((s))))", false));
|
|
|
4bff0a |
assert_se(signature_is_single("{ss}", true));
|
|
|
4bff0a |
assert_se(signature_is_single("a{ss}", false));
|
|
|
4bff0a |
@@ -63,7 +63,7 @@ int main(int argc, char *argv[]) {
|
|
|
4bff0a |
assert_se(signature_is_valid("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaas", false));
|
|
|
4bff0a |
assert_se(!signature_is_valid("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaau", false));
|
|
|
4bff0a |
|
|
|
4bff0a |
- assert_se(signature_is_valid("(((((((((((((((((((((((((((((((())))))))))))))))))))))))))))))))", false));
|
|
|
4bff0a |
+ assert_se(signature_is_valid("((((((((((((((((((((((((((((((((s))))))))))))))))))))))))))))))))", false));
|
|
|
4bff0a |
assert_se(!signature_is_valid("((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))", false));
|
|
|
4bff0a |
|
|
|
4bff0a |
assert_se(namespace_complex_pattern("", ""));
|
|
|
4bff0a |
diff --git a/test/fuzz/fuzz-bus-message/crash-26bba7182dedc8848939931d9fcefcb7922f2e56 b/test/fuzz/fuzz-bus-message/crash-26bba7182dedc8848939931d9fcefcb7922f2e56
|
|
|
4bff0a |
new file mode 100644
|
|
|
4bff0a |
index 0000000000000000000000000000000000000000..f1bf3229effc982c8b129182fe60739efe3c5013
|
|
|
4bff0a |
GIT binary patch
|
|
|
4bff0a |
literal 157
|
|
|
4bff0a |
mcmd1#|DTC5gMmSS0SHWtK_neOii>$FgGM4Akdcw0DF6TjSP;el
|
|
|
4bff0a |
|
|
|
4bff0a |
literal 0
|
|
|
4bff0a |
HcmV?d00001
|
|
|
4bff0a |
|
|
|
4bff0a |
diff --git a/test/fuzz/fuzz-bus-message/timeout-08ee8f6446a4064db064e8e0b3d220147f7d0b5b b/test/fuzz/fuzz-bus-message/timeout-08ee8f6446a4064db064e8e0b3d220147f7d0b5b
|
|
|
4bff0a |
new file mode 100644
|
|
|
4bff0a |
index 0000000000000000000000000000000000000000..c975f906eef521a3cfac5627c8b371ee55aa0e6c
|
|
|
4bff0a |
GIT binary patch
|
|
|
4bff0a |
literal 534
|
|
|
4bff0a |
zcmcJL!Ab-%42J(Y?m8o$d;nSS(q4Ae_Yi!A47)oFEOwaGU5e<<_x8`!K@h}~fslMn
|
|
|
4bff0a |
zn)c7Z!M!`6y9Pc0I2S?0hHh3l#W~|szZ;Ct$XAT}7+V?FCpm1RoiBemuU&_Ys%S@7
|
|
|
4bff0a |
zdCkYS>{AZe=OjL~Ie67zrCwgdYud(O^J==RG>!dpXFS^tlZIX@tK0h@{D4MV@hJsW
|
|
|
4bff0a |
zyR)R1zXEs6tHM*H04&I}2-7)y>9oE<hN&+5v>VCxw(Vn{LBxXmJ)=frMcRdZlJ-~v
|
|
|
4bff0a |
b#4gh=OPF@NW^U~wGO=l?@b9nvy
|
|
|
4bff0a |
|
|
|
4bff0a |
literal 0
|
|
|
4bff0a |
HcmV?d00001
|
|
|
4bff0a |
|