From 932da77b5be51ef63216d46255ad71863cf8ce89 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 21 Dec 2016 20:10:03 +0100 Subject: [PATCH] keyfile: assert that write_array_of_uint() writes valid integer list We use write_array_of_uint() for G_TYPE_ARRAY. In practice, only NMSettingDcb has any properties of this type. Furthermore, all valid values are either gboolean or guints of restricted range. Thus, no valid NMSettingDcb should violate the range check. Same for reader. It's really ugly to blindly use uint-list reader for G_TYPE_ARRAY. Especially, because certain G_TYPE_ARRAY properties of NMSettingDcb are actually arrays of gboolean, which only ~accidentally~ has the same memory layout as guint. --- libnm-core/nm-keyfile-reader.c | 15 ++++++++++----- libnm-core/nm-keyfile-writer.c | 16 +++++++++++----- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/libnm-core/nm-keyfile-reader.c b/libnm-core/nm-keyfile-reader.c index 15d8c88959..4403b8a256 100644 --- a/libnm-core/nm-keyfile-reader.c +++ b/libnm-core/nm-keyfile-reader.c @@ -108,19 +108,24 @@ read_array_of_uint (GKeyFile *file, NMSetting *setting, const char *key) { - GArray *array = NULL; + gs_unref_array GArray *array = NULL; gsize length; - int i; + gsize i; gs_free int *tmp = NULL; tmp = nm_keyfile_plugin_kf_get_integer_list (file, nm_setting_get_name (setting), key, &length, NULL); - array = g_array_sized_new (FALSE, FALSE, sizeof (guint32), length); + if (length > G_MAXUINT) + return; - for (i = 0; i < length; i++) + array = g_array_sized_new (FALSE, FALSE, sizeof (guint), length); + + for (i = 0; i < length; i++) { + if (tmp[i] < 0) + return; g_array_append_val (array, tmp[i]); + } g_object_set (setting, key, array, NULL); - g_array_unref (array); } static gboolean diff --git a/libnm-core/nm-keyfile-writer.c b/libnm-core/nm-keyfile-writer.c index d0e3effb42..0a54d4614a 100644 --- a/libnm-core/nm-keyfile-writer.c +++ b/libnm-core/nm-keyfile-writer.c @@ -73,19 +73,25 @@ write_array_of_uint (GKeyFile *file, const GValue *value) { GArray *array; - int i; - int *tmp_array; + guint i; + gs_free int *tmp_array = NULL; array = (GArray *) g_value_get_boxed (value); if (!array || !array->len) return; + g_return_if_fail (g_array_get_element_size (array) == sizeof (guint)); + tmp_array = g_new (gint, array->len); - for (i = 0; i < array->len; i++) - tmp_array[i] = g_array_index (array, int, i); + for (i = 0; i < array->len; i++) { + guint v = g_array_index (array, guint, i); + + if (v > G_MAXINT) + g_return_if_reached (); + tmp_array[i] = (int) v; + } nm_keyfile_plugin_kf_set_integer_list (file, nm_setting_get_name (setting), key, tmp_array, array->len); - g_free (tmp_array); } static void