ifcfg-rh: check integer value when reading handle_bridge_option()

We cannot just call g_object_set() with an integer that is out of bound.
Otherwise, glib will warn. We can use nm_g_object_set_property*() to return
an error without asserting.
This commit is contained in:
Thomas Haller
2017-11-23 16:30:31 +01:00
committed by Beniamino Galvani
parent 5befde7d7d
commit ff239c1652

View File

@@ -4661,48 +4661,66 @@ handle_bridge_option (NMSetting *setting,
const char *key, const char *key,
const char *value) const char *value)
{ {
static const struct {
const char *key;
const char *property_name;
gboolean only_with_stp;
} m/*etadata*/[] = {
{ "priority", NM_SETTING_BRIDGE_PRIORITY, TRUE },
{ "hello_time", NM_SETTING_BRIDGE_HELLO_TIME, TRUE },
{ "max_age", NM_SETTING_BRIDGE_MAX_AGE, TRUE },
{ "ageing_time", NM_SETTING_BRIDGE_AGEING_TIME, FALSE },
{ "multicast_snooping", NM_SETTING_BRIDGE_MULTICAST_SNOOPING, FALSE },
{ "group_fwd_mask", NM_SETTING_BRIDGE_GROUP_FORWARD_MASK, FALSE },
};
const char *error_message = NULL;
int i;
gint64 v; gint64 v;
guint32 u = 0;
if (!strcmp (key, "priority")) { for (i = 0; i < G_N_ELEMENTS (m); i++) {
if (stp == FALSE) GParamSpec *param_spec;
PARSE_WARNING ("'priority' invalid when STP is disabled");
else if ((v = _nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXUINT16, -1)) != -1) if (!nm_streq (key, m[i].key))
g_object_set (setting, NM_SETTING_BRIDGE_PRIORITY, (guint) v, NULL); continue;
else if (m[i].only_with_stp && !stp) {
PARSE_WARNING ("invalid priority value '%s'", value); PARSE_WARNING ("'%s' invalid when STP is disabled", key);
} else if (!strcmp (key, "hello_time")) { return;
if (stp == FALSE) }
PARSE_WARNING ("'hello_time' invalid when STP is disabled");
else if (get_uint32 (value, &u)) param_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), m[i].property_name);
g_object_set (setting, NM_SETTING_BRIDGE_HELLO_TIME, u, NULL); switch (param_spec->value_type) {
else case G_TYPE_BOOLEAN:
PARSE_WARNING ("invalid hello_time value '%s'", value); v = _nm_utils_ascii_str_to_int64 (value, 10, 0, 1, -1);
} else if (!strcmp (key, "max_age")) { if (v == -1) {
if (stp == FALSE) error_message = g_strerror (errno);
PARSE_WARNING ("'max_age' invalid when STP is disabled"); goto warn;
else if (get_uint32 (value, &u)) }
g_object_set (setting, NM_SETTING_BRIDGE_MAX_AGE, u, NULL); if (!nm_g_object_set_property_boolean (G_OBJECT (setting), m[i].property_name, v, NULL)) {
else error_message = "number is out of range";
PARSE_WARNING ("invalid max_age value '%s'", value); goto warn;
} else if (!strcmp (key, "ageing_time")) { }
if (get_uint32 (value, &u)) return;
g_object_set (setting, NM_SETTING_BRIDGE_AGEING_TIME, u, NULL); case G_TYPE_UINT:
else v = _nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXUINT, -1);
PARSE_WARNING ("invalid ageing_time value '%s'", value); if (v == -1) {
} else if (!strcmp (key, "multicast_snooping")) { error_message = g_strerror (errno);
if (get_uint32 (value, &u)) goto warn;
g_object_set (setting, NM_SETTING_BRIDGE_MULTICAST_SNOOPING, }
(gboolean) u, NULL); if (!nm_g_object_set_property_uint (G_OBJECT (setting), m[i].property_name, v, NULL)) {
else error_message = "number is out of range";
PARSE_WARNING ("invalid multicast_snooping value '%s'", value); goto warn;
} else if (!strcmp (key, "group_fwd_mask")) { }
if (get_uint32 (value, &u) && u <= 0xFFFF && !NM_FLAGS_ANY (u, 7)) return;
g_object_set (setting, NM_SETTING_BRIDGE_GROUP_FORWARD_MASK, default:
(gboolean) u, NULL); nm_assert_not_reached ();
else continue;
PARSE_WARNING ("invalid group_fwd_mask value '%s'", value); }
} else
warn:
PARSE_WARNING ("invalid %s value '%s': %s", key, value, error_message);
return;
}
PARSE_WARNING ("unhandled bridge option '%s'", key); PARSE_WARNING ("unhandled bridge option '%s'", key);
} }