From 613ecbfba04965bf48f78c3afbb9a99144cb6036 Mon Sep 17 00:00:00 2001 From: Will Thompson Date: Sun, 21 Nov 2010 16:34:51 +0000 Subject: [PATCH] Validate arg0namespace matches' values. I could be convinced that this is overkill, but it seems sensible to forbid obviously-broken arg0namespace matches. --- bus/signals.c | 68 ++++++++++++++++++++++++++++++++++++++++++++ dbus/dbus-marshal-validate.c | 66 ++++++++++++++++++++++++++++++------------ dbus/dbus-marshal-validate.h | 3 ++ 3 files changed, 119 insertions(+), 18 deletions(-) diff --git a/bus/signals.c b/bus/signals.c index 9939a23..daf8540 100644 --- a/bus/signals.c +++ b/bus/signals.c @@ -771,7 +771,22 @@ bus_match_rule_parse_arg_match (BusMatchRule *rule, } else if (_dbus_string_equal_c_str (&key_str, "arg0namespace")) { + int value_len = _dbus_string_get_length (value); + is_namespace = TRUE; + + if (value_len > 0 && + _dbus_string_get_byte (value, value_len - 1) == '.') + value_len--; + + if (!_dbus_validate_bus_namespace (value, 0, value_len)) + { + dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID, + "arg0namespace='%s' is not a valid (optionally " + "period-terminated) prefix of a bus name", + _dbus_string_get_const_data (value)); + goto failed; + } } else { @@ -2109,9 +2124,62 @@ test_parsing (void *data) bus_match_rule_unref (rule); } + rule = check_parse (TRUE, "arg0namespace='foo.'"); + if (rule != NULL) + { + _dbus_assert (rule->flags == BUS_MATCH_ARGS); + _dbus_assert (rule->args != NULL); + _dbus_assert (rule->args_len == 1); + _dbus_assert (strcmp (rule->args[0], "foo.") == 0); + _dbus_assert ((rule->arg_lens[0] & BUS_MATCH_ARG_NAMESPACE) + == BUS_MATCH_ARG_NAMESPACE); + + bus_match_rule_unref (rule); + } + + rule = check_parse (TRUE, "arg0namespace='foo.bar'"); + if (rule != NULL) + { + _dbus_assert (rule->flags == BUS_MATCH_ARGS); + _dbus_assert (rule->args != NULL); + _dbus_assert (rule->args_len == 1); + _dbus_assert (strcmp (rule->args[0], "foo.bar") == 0); + _dbus_assert ((rule->arg_lens[0] & BUS_MATCH_ARG_NAMESPACE) + == BUS_MATCH_ARG_NAMESPACE); + + bus_match_rule_unref (rule); + } + + rule = check_parse (TRUE, "arg0namespace='foo.bar.'"); + if (rule != NULL) + { + _dbus_assert (rule->flags == BUS_MATCH_ARGS); + _dbus_assert (rule->args != NULL); + _dbus_assert (rule->args_len == 1); + _dbus_assert (strcmp (rule->args[0], "foo.bar.") == 0); + _dbus_assert ((rule->arg_lens[0] & BUS_MATCH_ARG_NAMESPACE) + == BUS_MATCH_ARG_NAMESPACE); + + bus_match_rule_unref (rule); + } + + /* Only arg0namespace is supported. */ rule = check_parse (FALSE, "arg1namespace='foo'"); _dbus_assert (rule == NULL); + /* An empty string isn't a valid namespace prefix (you should just not + * specify this key at all). + */ + rule = check_parse (FALSE, "arg0namespace=''"); + _dbus_assert (rule == NULL); + + /* Two trailing periods on otherwise-valid namespaces aren't allowed. */ + rule = check_parse (FALSE, "arg0namespace='foo..'"); + _dbus_assert (rule == NULL); + + rule = check_parse (FALSE, "arg0namespace='foo.bar..'"); + _dbus_assert (rule == NULL); + /* Too-large argN */ rule = check_parse (FALSE, "arg300='foo'"); _dbus_assert (rule == NULL); diff --git a/dbus/dbus-marshal-validate.c b/dbus/dbus-marshal-validate.c index aa470fc..7d49624 100644 --- a/dbus/dbus-marshal-validate.c +++ b/dbus/dbus-marshal-validate.c @@ -1062,23 +1062,11 @@ _dbus_validate_error_name (const DBusString *str, ((c) >= 'a' && (c) <= 'z') || \ ((c) == '_') || ((c) == '-')) -/** - * Checks that the given range of the string is a valid bus name in - * the D-Bus protocol. This includes a length restriction, etc., see - * the specification. - * - * @todo this is inconsistent with most of DBusString in that - * it allows a start,len range that extends past the string end. - * - * @param str the string - * @param start first byte index to check - * @param len number of bytes to check - * @returns #TRUE if the byte range exists and is a valid name - */ -dbus_bool_t -_dbus_validate_bus_name (const DBusString *str, - int start, - int len) +static dbus_bool_t +_dbus_validate_bus_name_full (const DBusString *str, + int start, + int len, + dbus_bool_t is_namespace) { const unsigned char *s; const unsigned char *end; @@ -1156,13 +1144,55 @@ _dbus_validate_bus_name (const DBusString *str, ++s; } - if (_DBUS_UNLIKELY (last_dot == NULL)) + if (!is_namespace && _DBUS_UNLIKELY (last_dot == NULL)) return FALSE; return TRUE; } /** + * Checks that the given range of the string is a valid bus name in + * the D-Bus protocol. This includes a length restriction, etc., see + * the specification. + * + * @todo this is inconsistent with most of DBusString in that + * it allows a start,len range that extends past the string end. + * + * @param str the string + * @param start first byte index to check + * @param len number of bytes to check + * @returns #TRUE if the byte range exists and is a valid name + */ +dbus_bool_t +_dbus_validate_bus_name (const DBusString *str, + int start, + int len) +{ + return _dbus_validate_bus_name_full (str, start, len, FALSE); +} + +/** + * Checks that the given range of the string is a prefix of a valid bus name in + * the D-Bus protocol. Unlike _dbus_validate_bus_name(), this accepts strings + * with only one period-separated component. + * + * @todo this is inconsistent with most of DBusString in that + * it allows a start,len range that extends past the string end. + * + * @param str the string + * @param start first byte index to check + * @param len number of bytes to check + * @returns #TRUE if the byte range exists and is a valid name + */ +dbus_bool_t +_dbus_validate_bus_namespace (const DBusString *str, + int start, + int len) +{ + return _dbus_validate_bus_name_full (str, start, len, TRUE); +} + +/** * Checks that the given range of the string is a valid message type * signature in the D-Bus protocol. * diff --git a/dbus/dbus-marshal-validate.h b/dbus/dbus-marshal-validate.h index 5817de3..9b89608 100644 --- a/dbus/dbus-marshal-validate.h +++ b/dbus/dbus-marshal-validate.h @@ -143,6 +143,9 @@ dbus_bool_t _dbus_validate_error_name (const DBusString *str, dbus_bool_t _dbus_validate_bus_name (const DBusString *str, int start, int len); +dbus_bool_t _dbus_validate_bus_namespace (const DBusString *str, + int start, + int len); dbus_bool_t _dbus_validate_signature (const DBusString *str, int start, int len); -- 2.7.4