diff options
author | Thomas Haller <thaller@redhat.com> | 2016-12-21 20:10:03 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2017-01-04 15:14:46 +0100 |
commit | ce7e9b293d7a67d744260cfed9fa47cda64b4b05 (patch) | |
tree | 7894a785dd9b1b815f5bc8804c4757d38af3e38b | |
parent | ec35e0f077900c174314da8332cbe70368c155ab (diff) | |
download | NetworkManager-th/keyfile-parsing-bgo776484.tar.gz |
keyfile: assert that write_array_of_uint() writes valid integer listth/keyfile-parsing-bgo776484
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.
-rw-r--r-- | libnm-core/nm-keyfile-reader.c | 15 | ||||
-rw-r--r-- | 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 56ae52de39..fee01c97f3 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; + + array = g_array_sized_new (FALSE, FALSE, sizeof (guint), length); - for (i = 0; i < length; i++) + 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 |