From 5e389fdf499c39926c61b47fcafb5e71291ce1a2 Mon Sep 17 00:00:00 2001 From: "John (J5) Palmieri" Date: Wed, 15 Jun 2005 15:15:32 +0000 Subject: * dbus/dbus-marshal-validate.h: Added a new validation error code DBUS_VALIDITY_UNKNOWN_OOM_ERROR = -4 for out of memory errors when validating signitures * dbus/dbus-marshal-header.c: use DBUS_VALIDITY_UNKNOWN_OOM_ERROR in places where we previously used DBUS_VALID and a FALSE return value to indicate OOM * dbus/dbus-marshal-validate.c (_dbus_validate_signature_with_reason): Use a stack to track the number of elements inside containers. The stack values are then used to validate that dict entries have only two elements within them. (validate_body_helper): check the reason for failure when validating varients * dbus/dbus-message.c (load_message): use DBUS_VALIDITY_UNKNOWN_OOM_ERROR in places where we previously used DBUS_VALID and a FALSE return value to indicate OOM * doc/TODO: remove "- validate dict entry number of fields" as this patch fixes it --- dbus/dbus-marshal-validate.c | 184 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 151 insertions(+), 33 deletions(-) (limited to 'dbus/dbus-marshal-validate.c') diff --git a/dbus/dbus-marshal-validate.c b/dbus/dbus-marshal-validate.c index dbe2fa54..92050a59 100644 --- a/dbus/dbus-marshal-validate.c +++ b/dbus/dbus-marshal-validate.c @@ -61,6 +61,19 @@ _dbus_validate_signature_with_reason (const DBusString *type_str, int struct_depth; int array_depth; int dict_entry_depth; + DBusValidity result; + + int element_count; + DBusList *element_count_stack; + + result = DBUS_VALID; + element_count_stack = NULL; + + if (!_dbus_list_append (&element_count_stack, _DBUS_INT_TO_POINTER (0))) + { + result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR; + goto out; + } _dbus_assert (type_str != NULL); _dbus_assert (type_pos < _DBUS_INT32_MAX - len); @@ -68,9 +81,13 @@ _dbus_validate_signature_with_reason (const DBusString *type_str, _dbus_assert (type_pos >= 0); if (len > DBUS_MAXIMUM_SIGNATURE_LENGTH) - return DBUS_INVALID_SIGNATURE_TOO_LONG; + { + result = DBUS_INVALID_SIGNATURE_TOO_LONG; + goto out; + } p = _dbus_string_get_const_data_len (type_str, type_pos, 0); + end = _dbus_string_get_const_data_len (type_str, type_pos + len, 0); struct_depth = 0; array_depth = 0; @@ -99,85 +116,179 @@ _dbus_validate_signature_with_reason (const DBusString *type_str, case DBUS_TYPE_ARRAY: array_depth += 1; if (array_depth > DBUS_MAXIMUM_TYPE_RECURSION_DEPTH) - return DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION; + { + result = DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION; + goto out; + } break; case DBUS_STRUCT_BEGIN_CHAR: struct_depth += 1; if (struct_depth > DBUS_MAXIMUM_TYPE_RECURSION_DEPTH) - return DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION; + { + result = DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION; + goto out; + } + + if (!_dbus_list_append (&element_count_stack, + _DBUS_INT_TO_POINTER (0))) + { + result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR; + goto out; + } + break; case DBUS_STRUCT_END_CHAR: if (struct_depth == 0) - return DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED; + { + result = DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED; + goto out; + } if (last == DBUS_STRUCT_BEGIN_CHAR) - return DBUS_INVALID_STRUCT_HAS_NO_FIELDS; + { + result = DBUS_INVALID_STRUCT_HAS_NO_FIELDS; + goto out; + } + + _dbus_list_pop_last (&element_count_stack); struct_depth -= 1; break; case DBUS_DICT_ENTRY_BEGIN_CHAR: if (last != DBUS_TYPE_ARRAY) - return DBUS_INVALID_DICT_ENTRY_NOT_INSIDE_ARRAY; - + { + result = DBUS_INVALID_DICT_ENTRY_NOT_INSIDE_ARRAY; + goto out; + } + dict_entry_depth += 1; if (dict_entry_depth > DBUS_MAXIMUM_TYPE_RECURSION_DEPTH) - return DBUS_INVALID_EXCEEDED_MAXIMUM_DICT_ENTRY_RECURSION; + { + result = DBUS_INVALID_EXCEEDED_MAXIMUM_DICT_ENTRY_RECURSION; + goto out; + } + + if (!_dbus_list_append (&element_count_stack, + _DBUS_INT_TO_POINTER (0))) + { + result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR; + goto out; + } + break; case DBUS_DICT_ENTRY_END_CHAR: if (dict_entry_depth == 0) - return DBUS_INVALID_DICT_ENTRY_ENDED_BUT_NOT_STARTED; - - if (last == DBUS_DICT_ENTRY_BEGIN_CHAR) - return DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS; - + { + result = DBUS_INVALID_DICT_ENTRY_ENDED_BUT_NOT_STARTED; + goto out; + } + dict_entry_depth -= 1; + + element_count = + _DBUS_POINTER_TO_INT (_dbus_list_pop_last (&element_count_stack)); + + if (element_count != 2) + { + if (element_count == 0) + result = DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS; + else if (element_count == 1) + result = DBUS_INVALID_DICT_ENTRY_HAS_ONLY_ONE_FIELD; + else + result = DBUS_INVALID_DICT_ENTRY_HAS_TOO_MANY_FIELDS; + + goto out; + } break; case DBUS_TYPE_STRUCT: /* doesn't appear in signatures */ case DBUS_TYPE_DICT_ENTRY: /* ditto */ default: - return DBUS_INVALID_UNKNOWN_TYPECODE; + result = DBUS_INVALID_UNKNOWN_TYPECODE; + goto out; } + if (*p != DBUS_TYPE_ARRAY && + *p != DBUS_DICT_ENTRY_BEGIN_CHAR && + *p != DBUS_STRUCT_BEGIN_CHAR) + { + element_count = + _DBUS_POINTER_TO_INT (_dbus_list_pop_last (&element_count_stack)); + + ++element_count; + + if (!_dbus_list_append (&element_count_stack, + _DBUS_INT_TO_POINTER (element_count))) + { + result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR; + goto out; + } + } + if (array_depth > 0) { - if (*p == DBUS_TYPE_ARRAY) - ; - else if (*p == DBUS_STRUCT_END_CHAR || - *p == DBUS_DICT_ENTRY_END_CHAR) - return DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE; + if (*p == DBUS_TYPE_ARRAY && p != end) + { + const char *p1; + p1 = p + 1; + if (*p1 == DBUS_STRUCT_END_CHAR || + *p1 == DBUS_DICT_ENTRY_END_CHAR) + { + result = DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE; + goto out; + } + } else - array_depth = 0; + { + array_depth = 0; + } } if (last == DBUS_DICT_ENTRY_BEGIN_CHAR && !dbus_type_is_basic (*p)) - return DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE; - + { + result = DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE; + goto out; + } + last = *p; ++p; } - if (array_depth > 0) - return DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE; + if (array_depth > 0) + { + result = DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE; + goto out; + } + if (struct_depth > 0) - return DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED; - + { + result = DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED; + goto out; + } + if (dict_entry_depth > 0) - return DBUS_INVALID_DICT_ENTRY_STARTED_BUT_NOT_ENDED; - + { + result = DBUS_INVALID_DICT_ENTRY_STARTED_BUT_NOT_ENDED; + goto out; + } + _dbus_assert (last != DBUS_TYPE_ARRAY); _dbus_assert (last != DBUS_STRUCT_BEGIN_CHAR); _dbus_assert (last != DBUS_DICT_ENTRY_BEGIN_CHAR); - - return DBUS_VALID; + + result = DBUS_VALID; + +out: + _dbus_list_clear (&element_count_stack); + return result; } static DBusValidity @@ -387,6 +498,7 @@ validate_body_helper (DBusTypeReader *reader, DBusValidity validity; int contained_alignment; int contained_type; + DBusValidity reason; claimed_len = *p; ++p; @@ -396,9 +508,15 @@ validate_body_helper (DBusTypeReader *reader, return DBUS_INVALID_VARIANT_SIGNATURE_LENGTH_OUT_OF_BOUNDS; _dbus_string_init_const_len (&sig, p, claimed_len); - if (!_dbus_validate_signature (&sig, 0, - _dbus_string_get_length (&sig))) - return DBUS_INVALID_VARIANT_SIGNATURE_BAD; + reason = _dbus_validate_signature_with_reason (&sig, 0, + _dbus_string_get_length (&sig)); + if (!(reason == DBUS_VALID)) + { + if (reason == DBUS_VALIDITY_UNKNOWN_OOM_ERROR) + return reason; + else + return DBUS_INVALID_VARIANT_SIGNATURE_BAD; + } p += claimed_len; -- cgit