core: fix crash in nm_netns_ip_route_ecmp_commit()

#0  0x00000000004c53e0 in nm_netns_ip_route_ecmp_commit (self=0x27bde30, l3cfg=l3cfg@entry=0x2890810, out_singlehop_routes=out_singlehop_routes@entry=0x7ffd0cac3ce8)
      at src/core/nm-netns.c:686
  #1  0x00000000004b4335 in _commit_collect_routes
      (self=self@entry=0x2890810, addr_family=addr_family@entry=2, commit_type=commit_type@entry=NM_L3_CFG_COMMIT_TYPE_UPDATE, routes=routes@entry=0x7ffd0cac3de8, routes_nodev=routes_nodev@entry=0x7ffd0cac3de0) at src/core/nm-l3cfg.c:1183
  #2  0x00000000004b8982 in _l3_commit_one
      (self=self@entry=0x2890810, addr_family=addr_family@entry=2, commit_type=commit_type@entry=NM_L3_CFG_COMMIT_TYPE_UPDATE, changed_combined_l3cd=<optimized out>, l3cd_old=<optimized out>) at src/core/nm-l3cfg.c:4605
  #3  0x00000000004c0f52 in _l3_commit (self=self@entry=0x2890810, commit_type=NM_L3_CFG_COMMIT_TYPE_UPDATE, commit_type@entry=NM_L3_CFG_COMMIT_TYPE_AUTO, is_idle=is_idle@entry=1)
      at src/core/nm-l3cfg.c:4786
  #4  0x00000000004c11cb in _l3_commit_on_idle_cb (user_data=user_data@entry=0x2890810) at src/core/nm-l3cfg.c:3164
  #5  0x00007f532d02dcb2 in g_idle_dispatch (source=0x28f70c0, callback=0x4c116e <_l3_commit_on_idle_cb>, user_data=0x2890810) at ../glib/gmain.c:6124
  #6  0x00007f532d02ecbf in g_main_dispatch (context=0x27c2d60) at ../glib/gmain.c:3444

https://bugzilla.redhat.com/show_bug.cgi?id=2158365

Fixes: 5b5ce42682 ('nm-netns: track ECMP routes')
This commit is contained in:
Thomas Haller 2023-01-05 10:29:07 +01:00
parent ae7e7bf3d3
commit 6c81f281eb
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728

View file

@ -647,6 +647,11 @@ nm_netns_ip_route_ecmp_commit(NMNetns *self, NML3Cfg *l3cfg, GPtrArray **out_sin
track_ecmpid = track_obj->parent_track_ecmpid;
track_ecmpid->already_visited = FALSE;
nm_assert(g_hash_table_lookup(priv->ecmp_track_by_ecmpid, track_ecmpid) == track_ecmpid);
nm_assert(g_hash_table_lookup(priv->ecmp_track_by_obj, track_obj) == track_obj);
nm_assert(c_list_contains(&track_ecmpid->ecmpid_lst_head, &track_obj->ecmpid_lst));
nm_assert(track_obj->l3cfg == l3cfg);
if (!track_obj->dirty) {
/* This one is still in used. Keep it, but mark dirty, so that on the
* next update cycle, it needs to be touched again or will be deleted. */
@ -654,6 +659,10 @@ nm_netns_ip_route_ecmp_commit(NMNetns *self, NML3Cfg *l3cfg, GPtrArray **out_sin
continue;
}
/* This entry can be dropped. */
if (!g_hash_table_remove(priv->ecmp_track_by_obj, track_obj))
nm_assert_not_reached();
if (c_list_is_empty(&track_ecmpid->ecmpid_lst_head)) {
if (track_ecmpid->merged_obj) {
if (NMP_OBJECT_CAST_IP4_ROUTE(track_ecmpid->merged_obj)->n_nexthops > 1) {
@ -662,26 +671,14 @@ nm_netns_ip_route_ecmp_commit(NMNetns *self, NML3Cfg *l3cfg, GPtrArray **out_sin
g_ptr_array_new_with_free_func((GDestroyNotify) nmp_object_unref);
g_ptr_array_add(mhrts_del,
(gpointer) g_steal_pointer(&track_ecmpid->merged_obj));
} else {
if (track_obj->l3cfg != l3cfg) {
nm_l3cfg_commit_on_idle_schedule(track_obj->l3cfg,
NM_L3_CFG_COMMIT_TYPE_AUTO);
}
}
} else
nm_l3cfg_commit_on_idle_schedule(l3cfg, NM_L3_CFG_COMMIT_TYPE_AUTO);
}
g_hash_table_remove(priv->ecmp_track_by_ecmpid, track_ecmpid);
/* This entry can be dropped. */
if (!g_hash_table_remove(priv->ecmp_track_by_obj, &track_obj->obj))
nm_assert_not_reached();
continue;
}
/* This entry can be dropped. */
if (!g_hash_table_remove(priv->ecmp_track_by_obj, &track_obj->obj))
nm_assert_not_reached();
/* We need to update the representative obj. */
nmp_object_ref_set(
&track_ecmpid->representative_obj,