mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-24 08:40:26 +01:00
libnm-core: validate property types from D-Bus (rh #1182567)
In _nm_setting_new_from_dbus(), verify that the properties have the
right types, and return an error if not. (In particular, don't crash
if someone tries to assign a GBytes-valued property a non-'ay' value.)
(cherry picked from commit 76d9fc9167)
This commit is contained in:
parent
25c61dc805
commit
f40a69f624
2 changed files with 225 additions and 7 deletions
|
|
@ -660,17 +660,40 @@ get_property_for_dbus (NMSetting *setting,
|
|||
return dbus_value;
|
||||
}
|
||||
|
||||
static void
|
||||
set_property_from_dbus (const NMSettingProperty *property, GVariant *src_value, GValue *dst_value)
|
||||
static gboolean
|
||||
set_property_from_dbus (const NMSettingProperty *property,
|
||||
GVariant *src_value,
|
||||
GValue *dst_value)
|
||||
{
|
||||
g_return_if_fail (property->param_spec != NULL);
|
||||
|
||||
if (property->from_dbus)
|
||||
if (property->from_dbus) {
|
||||
if (!g_variant_type_equal (g_variant_get_type (src_value), property->dbus_type))
|
||||
return FALSE;
|
||||
|
||||
property->from_dbus (src_value, dst_value);
|
||||
else if (dst_value->g_type == G_TYPE_BYTES)
|
||||
} else if (dst_value->g_type == G_TYPE_BYTES) {
|
||||
if (!g_variant_is_of_type (src_value, G_VARIANT_TYPE_BYTESTRING))
|
||||
return FALSE;
|
||||
|
||||
_nm_utils_bytes_from_dbus (src_value, dst_value);
|
||||
else
|
||||
g_dbus_gvariant_to_gvalue (src_value, dst_value);
|
||||
} else {
|
||||
GValue tmp = G_VALUE_INIT;
|
||||
|
||||
g_dbus_gvariant_to_gvalue (src_value, &tmp);
|
||||
if (G_VALUE_TYPE (&tmp) == G_VALUE_TYPE (dst_value))
|
||||
*dst_value = tmp;
|
||||
else {
|
||||
gboolean success;
|
||||
|
||||
success = g_value_transform (&tmp, dst_value);
|
||||
g_value_unset (&tmp);
|
||||
if (!success)
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -798,6 +821,21 @@ _nm_setting_new_from_dbus (GType setting_type,
|
|||
value = g_variant_lookup_value (setting_dict, property->name, NULL);
|
||||
|
||||
if (value && property->set_func) {
|
||||
if (!g_variant_type_equal (g_variant_get_type (value), property->dbus_type)) {
|
||||
property_type_error:
|
||||
g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
_("can't set property of type '%s' from value of type '%s'"),
|
||||
property->dbus_type ?
|
||||
g_variant_type_peek_string (property->dbus_type) :
|
||||
g_type_name (property->param_spec->value_type),
|
||||
g_variant_get_type_string (value));
|
||||
g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), property->name);
|
||||
|
||||
g_variant_unref (value);
|
||||
g_object_unref (setting);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
property->set_func (setting,
|
||||
connection_dict,
|
||||
property->name,
|
||||
|
|
@ -810,7 +848,9 @@ _nm_setting_new_from_dbus (GType setting_type,
|
|||
GValue object_value = { 0, };
|
||||
|
||||
g_value_init (&object_value, property->param_spec->value_type);
|
||||
set_property_from_dbus (property, value, &object_value);
|
||||
if (!set_property_from_dbus (property, value, &object_value))
|
||||
goto property_type_error;
|
||||
|
||||
g_object_set_property (G_OBJECT (setting), property->param_spec->name, &object_value);
|
||||
g_value_unset (&object_value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1140,6 +1140,183 @@ test_setting_new_from_dbus_enum (void)
|
|||
g_object_unref (s_serial);
|
||||
}
|
||||
|
||||
static void
|
||||
test_setting_new_from_dbus_bad (void)
|
||||
{
|
||||
NMSetting *setting;
|
||||
NMConnection *conn;
|
||||
GBytes *ssid;
|
||||
GPtrArray *addrs;
|
||||
GVariant *orig_dict, *dict;
|
||||
GError *error = NULL;
|
||||
|
||||
/* We want to test:
|
||||
* - ordinary scalar properties
|
||||
* - string properties
|
||||
* - GBytes-valued properties (which are handled specially by set_property_from_dbus())
|
||||
* - enum/flags-valued properties
|
||||
* - overridden properties
|
||||
* - transformed properties
|
||||
*
|
||||
* No single setting class has examples of all of these, so we need two settings.
|
||||
*/
|
||||
|
||||
conn = nm_simple_connection_new ();
|
||||
|
||||
setting = nm_setting_connection_new ();
|
||||
g_object_set (setting,
|
||||
NM_SETTING_CONNECTION_ID, "test",
|
||||
NM_SETTING_CONNECTION_UUID, "83c5a841-1759-4cdb-bfce-8d4087956497",
|
||||
NULL);
|
||||
nm_connection_add_setting (conn, setting);
|
||||
|
||||
setting = nm_setting_wireless_new ();
|
||||
ssid = g_bytes_new ("my-ssid", 7);
|
||||
g_object_set (setting,
|
||||
/* scalar */
|
||||
NM_SETTING_WIRELESS_RATE, 100,
|
||||
/* string */
|
||||
NM_SETTING_WIRELESS_MODE, NM_SETTING_WIRELESS_MODE_INFRA,
|
||||
/* GBytes */
|
||||
NM_SETTING_WIRELESS_SSID, ssid,
|
||||
/* transformed */
|
||||
NM_SETTING_WIRELESS_BSSID, "00:11:22:33:44:55",
|
||||
NULL);
|
||||
g_bytes_unref (ssid);
|
||||
nm_connection_add_setting (conn, setting);
|
||||
|
||||
setting = nm_setting_ip6_config_new ();
|
||||
addrs = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_address_unref);
|
||||
g_ptr_array_add (addrs, nm_ip_address_new (AF_INET6, "1234::5678", 64, NULL));
|
||||
g_object_set (setting,
|
||||
/* enum */
|
||||
NM_SETTING_IP6_CONFIG_IP6_PRIVACY, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR,
|
||||
/* overridden */
|
||||
NM_SETTING_IP_CONFIG_ADDRESSES, addrs,
|
||||
/* (needed in order to verify()) */
|
||||
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO,
|
||||
NULL);
|
||||
g_ptr_array_unref (addrs);
|
||||
nm_connection_add_setting (conn, setting);
|
||||
|
||||
orig_dict = nm_connection_to_dbus (conn, NM_CONNECTION_SERIALIZE_ALL);
|
||||
g_object_unref (conn);
|
||||
|
||||
/* sanity-check */
|
||||
conn = nm_simple_connection_new_from_dbus (orig_dict, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (conn);
|
||||
g_object_unref (conn);
|
||||
|
||||
/* Compatible mismatches */
|
||||
|
||||
dict = g_variant_ref (orig_dict);
|
||||
NMTST_VARIANT_EDITOR (dict,
|
||||
NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_WIRELESS_SETTING_NAME,
|
||||
NM_SETTING_WIRELESS_RATE,
|
||||
"i", 10);
|
||||
);
|
||||
conn = nm_simple_connection_new_from_dbus (dict, &error);
|
||||
g_assert (conn);
|
||||
g_assert_no_error (error);
|
||||
setting = nm_connection_get_setting (conn, NM_TYPE_SETTING_WIRELESS);
|
||||
g_assert (setting);
|
||||
g_assert_cmpint (nm_setting_wireless_get_rate (NM_SETTING_WIRELESS (setting)), ==, 10);
|
||||
g_object_unref (conn);
|
||||
g_variant_unref (dict);
|
||||
|
||||
dict = g_variant_ref (orig_dict);
|
||||
NMTST_VARIANT_EDITOR (dict,
|
||||
NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
||||
NM_SETTING_IP6_CONFIG_IP6_PRIVACY,
|
||||
"i", NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR);
|
||||
);
|
||||
conn = nm_simple_connection_new_from_dbus (dict, &error);
|
||||
g_assert (conn);
|
||||
g_assert_no_error (error);
|
||||
setting = nm_connection_get_setting (conn, NM_TYPE_SETTING_IP6_CONFIG);
|
||||
g_assert (setting);
|
||||
g_assert_cmpint (nm_setting_ip6_config_get_ip6_privacy (NM_SETTING_IP6_CONFIG (setting)), ==, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR);
|
||||
g_object_unref (conn);
|
||||
g_variant_unref (dict);
|
||||
|
||||
/* Incompatible mismatches */
|
||||
|
||||
dict = g_variant_ref (orig_dict);
|
||||
NMTST_VARIANT_EDITOR (dict,
|
||||
NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_WIRELESS_SETTING_NAME,
|
||||
NM_SETTING_WIRELESS_RATE,
|
||||
"s", "ten");
|
||||
);
|
||||
conn = nm_simple_connection_new_from_dbus (dict, &error);
|
||||
g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
|
||||
g_assert (g_str_has_prefix (error->message, "802-11-wireless.rate:"));
|
||||
g_clear_error (&error);
|
||||
g_variant_unref (dict);
|
||||
|
||||
dict = g_variant_ref (orig_dict);
|
||||
NMTST_VARIANT_EDITOR (dict,
|
||||
NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_WIRELESS_SETTING_NAME,
|
||||
NM_SETTING_WIRELESS_MODE,
|
||||
"b", FALSE);
|
||||
);
|
||||
conn = nm_simple_connection_new_from_dbus (dict, &error);
|
||||
g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
|
||||
g_assert (g_str_has_prefix (error->message, "802-11-wireless.mode:"));
|
||||
g_clear_error (&error);
|
||||
g_variant_unref (dict);
|
||||
|
||||
dict = g_variant_ref (orig_dict);
|
||||
NMTST_VARIANT_EDITOR (dict,
|
||||
NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_WIRELESS_SETTING_NAME,
|
||||
NM_SETTING_WIRELESS_SSID,
|
||||
"s", "fred");
|
||||
);
|
||||
conn = nm_simple_connection_new_from_dbus (dict, &error);
|
||||
g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
|
||||
g_assert (g_str_has_prefix (error->message, "802-11-wireless.ssid:"));
|
||||
g_clear_error (&error);
|
||||
g_variant_unref (dict);
|
||||
|
||||
dict = g_variant_ref (orig_dict);
|
||||
NMTST_VARIANT_EDITOR (dict,
|
||||
NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_WIRELESS_SETTING_NAME,
|
||||
NM_SETTING_WIRELESS_BSSID,
|
||||
"i", 42);
|
||||
);
|
||||
conn = nm_simple_connection_new_from_dbus (dict, &error);
|
||||
g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
|
||||
g_assert (g_str_has_prefix (error->message, "802-11-wireless.bssid:"));
|
||||
g_clear_error (&error);
|
||||
g_variant_unref (dict);
|
||||
|
||||
dict = g_variant_ref (orig_dict);
|
||||
NMTST_VARIANT_EDITOR (dict,
|
||||
NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
||||
NM_SETTING_IP6_CONFIG_IP6_PRIVACY,
|
||||
"s", "private");
|
||||
);
|
||||
conn = nm_simple_connection_new_from_dbus (dict, &error);
|
||||
g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
|
||||
g_assert (g_str_has_prefix (error->message, "ipv6.ip6-privacy:"));
|
||||
g_clear_error (&error);
|
||||
g_variant_unref (dict);
|
||||
|
||||
dict = g_variant_ref (orig_dict);
|
||||
NMTST_VARIANT_EDITOR (dict,
|
||||
NMTST_VARIANT_CHANGE_PROPERTY (NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
||||
NM_SETTING_IP_CONFIG_ADDRESSES,
|
||||
"s", "1234::5678");
|
||||
);
|
||||
conn = nm_simple_connection_new_from_dbus (dict, &error);
|
||||
g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
|
||||
g_assert (g_str_has_prefix (error->message, "ipv6.addresses:"));
|
||||
g_clear_error (&error);
|
||||
g_variant_unref (dict);
|
||||
|
||||
g_variant_unref (orig_dict);
|
||||
}
|
||||
|
||||
static NMConnection *
|
||||
new_test_connection (void)
|
||||
{
|
||||
|
|
@ -3901,6 +4078,7 @@ int main (int argc, char **argv)
|
|||
g_test_add_func ("/core/general/test_setting_new_from_dbus", test_setting_new_from_dbus);
|
||||
g_test_add_func ("/core/general/test_setting_new_from_dbus_transform", test_setting_new_from_dbus_transform);
|
||||
g_test_add_func ("/core/general/test_setting_new_from_dbus_enum", test_setting_new_from_dbus_enum);
|
||||
g_test_add_func ("/core/general/test_setting_new_from_dbus_bad", test_setting_new_from_dbus_bad);
|
||||
g_test_add_func ("/core/general/test_connection_replace_settings", test_connection_replace_settings);
|
||||
g_test_add_func ("/core/general/test_connection_replace_settings_from_connection", test_connection_replace_settings_from_connection);
|
||||
g_test_add_func ("/core/general/test_connection_replace_settings_bad", test_connection_replace_settings_bad);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue