Skip to content

Commit f70c447

Browse files
committed
nm: fix crashes when errors are ignored
When --ignore-errors is used, some netdefs might arrive at the NM config writers in a bad state. In such cases we just skip them. Found with config_fuzzer.
1 parent 0bd688e commit f70c447

File tree

2 files changed

+55
-4
lines changed

2 files changed

+55
-4
lines changed

src/nm.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,10 @@ type_str(const NetplanNetDefinition* def)
100100
g_assert(def->backend_settings.passthrough != NULL);
101101
GHashTable *passthrough = def->backend_settings.passthrough;
102102
GHashTable* connection = g_hash_table_lookup(passthrough, "connection");
103-
return g_hash_table_lookup(connection, "type");
103+
if (connection) {
104+
return g_hash_table_lookup(connection, "type");
105+
}
106+
return NULL;
104107
// LCOV_EXCL_START
105108
default:
106109
g_assert_not_reached();
@@ -634,6 +637,12 @@ write_nm_conf_access_point(const NetplanNetDefinition* def, const char* rootdir,
634637
else
635638
g_assert(ap == NULL);
636639

640+
nm_type = type_str(def);
641+
if (def->type == NETPLAN_DEF_TYPE_NM && nm_type == NULL) {
642+
g_set_error(error, NETPLAN_BACKEND_ERROR, NETPLAN_ERROR_UNSUPPORTED, "ERROR: %s: NetworkManager connection type undefined\n", def->id);
643+
return FALSE;
644+
}
645+
637646
if (def->type == NETPLAN_DEF_TYPE_VLAN && def->sriov_vlan_filter) {
638647
g_debug("%s is defined as a hardware SR-IOV filtered VLAN, postponing creation", def->id);
639648
return TRUE;
@@ -653,7 +662,6 @@ write_nm_conf_access_point(const NetplanNetDefinition* def, const char* rootdir,
653662
g_key_file_set_string(kf, "connection", "id", nd_nm_id);
654663
}
655664

656-
nm_type = type_str(def);
657665
if (nm_type && def->type != NETPLAN_DEF_TYPE_NM)
658666
g_key_file_set_string(kf, "connection", "type", nm_type);
659667

@@ -1082,11 +1090,21 @@ netplan_state_finish_nm_write(
10821090
GString *tmp = NULL;
10831091
guint unmanaged = nd->backend == NETPLAN_BACKEND_NM ? 0 : 1;
10841092

1093+
if (nd->type == NETPLAN_DEF_TYPE_NM_PLACEHOLDER_ || nd->backend == NETPLAN_BACKEND_OVS) {
1094+
iter = iter->next;
1095+
continue;
1096+
}
1097+
1098+
nm_type = type_str(nd);
1099+
if (nd->type == NETPLAN_DEF_TYPE_NM && nm_type == NULL) {
1100+
/* Will happen when errors are ignored */
1101+
iter = iter->next;
1102+
continue;
1103+
}
1104+
10851105
g_autofree char* netdef_id = _netplan_scrub_string(nd->id);
10861106
/* Special case: manage or ignore any device of given type on empty "match: {}" stanza */
10871107
if (nd->has_match && !nd->match.driver && !nd->match.mac && !nd->match.original_name) {
1088-
nm_type = type_str(nd);
1089-
g_assert(nm_type != NULL);
10901108
g_string_append_printf(nm_conf, "[device-netplan.%s.%s]\nmatch-device=type:%s\n"
10911109
"managed=%d\n\n", netplan_def_type_name(nd->type),
10921110
netdef_id, nm_type, !unmanaged);

tests/generator/test_passthrough.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,39 @@ def test_passthrough_basic_new_format_with_duplication(self):
137137
match-device=type:ethernet
138138
managed=1\n\n''')
139139

140+
def test_passthrough_basic_new_format_no_type_ignore_error(self):
141+
out = self.generate('''network:
142+
version: 2
143+
nm-devices:
144+
NM-87749f1d-334f-40b2-98d4-55db58965f5f:
145+
renderer: NetworkManager
146+
match: {}
147+
networkmanager:
148+
uuid: 87749f1d-334f-40b2-98d4-55db58965f5f
149+
name: some NM id
150+
passthrough:
151+
connection:
152+
uuid: 87749f1d-334f-40b2-98d4-55db58965f5f
153+
permissions: ""''', skip_generated_yaml_validation=True, ignore_errors=True)
154+
155+
self.assertIn('network type \'nm-devices:\' needs to provide a \'connection.type\'', out)
156+
157+
def test_passthrough_basic_new_format_no_connection_ignore_error(self):
158+
out = self.generate('''network:
159+
version: 2
160+
nm-devices:
161+
NM-87749f1d-334f-40b2-98d4-55db58965f5f:
162+
renderer: NetworkManager
163+
match: {}
164+
networkmanager:
165+
uuid: 87749f1d-334f-40b2-98d4-55db58965f5f
166+
name: some NM id
167+
passthrough:
168+
a:
169+
b: c''', skip_generated_yaml_validation=True, ignore_errors=True)
170+
171+
self.assertIn('network type \'nm-devices:\' needs to provide a \'connection.type\'', out)
172+
140173
def test_passthrough_wifi(self):
141174
self.generate('''network:
142175
version: 2

0 commit comments

Comments
 (0)