From cd443376769a0be8295b4c390f9abe2984d032f3 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Sun, 12 Dec 2010 21:08:43 -0500 Subject: [PATCH 1/2] Add DBUS_INVALID_NESTED_TOO_DEEPLY validity problem and a test that should generate it The thing we want to detect is too much "dynamic nesting" due to variants. The new test currently fails because we don't validate this. For now the nesting limit is 64, which was also the limit in static signatures. See https://bugs.freedesktop.org/show_bug.cgi?id=32321 --- dbus/dbus-marshal-validate.c | 2 +- dbus/dbus-marshal-validate.h | 1 + dbus/dbus-message-factory.c | 65 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 1 deletions(-) diff --git a/dbus/dbus-marshal-validate.c b/dbus/dbus-marshal-validate.c index aa470fc..b5d7dae 100644 --- a/dbus/dbus-marshal-validate.c +++ b/dbus/dbus-marshal-validate.c @@ -878,7 +878,7 @@ _dbus_validity_to_error_message (DBusValidity validity) case DBUS_INVALID_DICT_ENTRY_HAS_TOO_MANY_FIELDS: return "Dict entry has too many fields"; case DBUS_INVALID_DICT_ENTRY_NOT_INSIDE_ARRAY: return "Dict entry not inside array"; case DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE: return "Dict key must be basic type"; - + case DBUS_INVALID_NESTED_TOO_DEEPLY: return "Variants cannot be used to create a hugely recursive tree of values"; default: return "Invalid"; } diff --git a/dbus/dbus-marshal-validate.h b/dbus/dbus-marshal-validate.h index 5817de3..8947a2a 100644 --- a/dbus/dbus-marshal-validate.h +++ b/dbus/dbus-marshal-validate.h @@ -112,6 +112,7 @@ typedef enum DBUS_INVALID_DICT_ENTRY_NOT_INSIDE_ARRAY = 54, DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE = 55, DBUS_INVALID_MISSING_UNIX_FDS = 56, + DBUS_INVALID_NESTED_TOO_DEEPLY = 57, DBUS_VALIDITY_LAST } DBusValidity; diff --git a/dbus/dbus-message-factory.c b/dbus/dbus-message-factory.c index 7432cf2..7ecf827 100644 --- a/dbus/dbus-message-factory.c +++ b/dbus/dbus-message-factory.c @@ -333,6 +333,53 @@ simple_error (void) return message; } +static DBusMessage* +message_with_nesting_levels (int levels) +{ + DBusMessage *message; + dbus_int32_t v_INT32; + DBusMessageIter *parents; + DBusMessageIter *children; + int i; + + /* If levels is higher it breaks sig_refcount in DBusMessageRealIter + * in dbus-message.c, this assert is just to help you know you need + * to fix that if you hit it + */ + _dbus_assert (levels < 256); + + parents = dbus_new(DBusMessageIter, levels + 1); + children = dbus_new(DBusMessageIter, levels + 1); + + v_INT32 = 42; + message = simple_method_call (); + + i = 0; + dbus_message_iter_init_append (message, &parents[i]); + while (i < levels) + { + dbus_message_iter_open_container (&parents[i], DBUS_TYPE_VARIANT, + i == (levels - 1) ? + DBUS_TYPE_INT32_AS_STRING : + DBUS_TYPE_VARIANT_AS_STRING, + &children[i]); + ++i; + parents[i] = children[i-1]; + } + --i; + dbus_message_iter_append_basic (&children[i], DBUS_TYPE_INT32, &v_INT32); + while (i >= 0) + { + dbus_message_iter_close_container (&parents[i], &children[i]); + --i; + } + + dbus_free(parents); + dbus_free(children); + + return message; +} + static dbus_bool_t generate_special (DBusMessageDataIter *iter, DBusString *data, @@ -735,6 +782,24 @@ generate_special (DBusMessageDataIter *iter, *expected_validity = DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS; } + else if (item_seq == 20) + { + /* 64 levels of nesting is OK */ + message = message_with_nesting_levels(64); + + generate_from_message (data, expected_validity, message); + + *expected_validity = DBUS_VALID; + } + else if (item_seq == 21) + { + /* 65 levels of nesting is not OK */ + message = message_with_nesting_levels(65); + + generate_from_message (data, expected_validity, message); + + *expected_validity = DBUS_INVALID_NESTED_TOO_DEEPLY; + } else { return FALSE; -- 1.7.1