From ff6b14a658bf48d840e7a1e33386ca390498fe47 Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Mon, 29 May 2023 20:29:33 -0400 Subject: [PATCH] zebra: use ifindex vs ifp to avoid use-after-free on shutdown Signed-off-by: Christian Hopps --- zebra/zebra_evpn_mh.c | 22 +++++++++++++++------- zebra/zebra_evpn_mh.h | 2 ++ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/zebra/zebra_evpn_mh.c b/zebra/zebra_evpn_mh.c index 49120c2877..a5092c629a 100644 --- a/zebra/zebra_evpn_mh.c +++ b/zebra/zebra_evpn_mh.c @@ -535,19 +535,26 @@ static bool zebra_evpn_acc_vl_cmp(const void *p1, const void *p2) } /* Lookup VLAN based broadcast domain */ -struct zebra_evpn_access_bd *zebra_evpn_acc_vl_find(vlanid_t vid, - struct interface *br_if) +struct zebra_evpn_access_bd * +zebra_evpn_acc_vl_find_index(vlanid_t vid, ifindex_t bridge_ifindex) { struct zebra_evpn_access_bd *acc_bd; struct zebra_evpn_access_bd tmp; tmp.vid = vid; - tmp.bridge_ifindex = br_if->ifindex; + tmp.bridge_ifindex = bridge_ifindex; acc_bd = hash_lookup(zmh_info->evpn_vlan_table, &tmp); return acc_bd; } +/* Lookup VLAN based broadcast domain */ +struct zebra_evpn_access_bd *zebra_evpn_acc_vl_find(vlanid_t vid, + struct interface *br_if) +{ + return zebra_evpn_acc_vl_find_index(vid, br_if->ifindex); +} + /* A new broadcast domain can be created when a VLAN member or VLAN<=>VxLAN_IF * mapping is added. */ @@ -842,9 +849,9 @@ void zebra_evpn_access_bd_bridge_cleanup(vlanid_t vid, struct interface *br_if, void zebra_evpn_vxl_evpn_set(struct zebra_if *zif, struct zebra_evpn *zevpn, bool set) { - struct interface *br_if; struct zebra_vxlan_vni *vni; struct zebra_evpn_access_bd *acc_bd; + ifindex_t br_ifindex; if (!zif) return; @@ -854,11 +861,12 @@ void zebra_evpn_vxl_evpn_set(struct zebra_if *zif, struct zebra_evpn *zevpn, if (!vni) return; - br_if = zif->brslave_info.br_if; - if (!br_if) + /* Use the index as the pointer can be stale (deleted) */ + br_ifindex = zif->brslave_info.bridge_ifindex; + if (!zif->brslave_info.br_if || br_ifindex == IFINDEX_INTERNAL) return; - acc_bd = zebra_evpn_acc_vl_find(vni->access_vlan, br_if); + acc_bd = zebra_evpn_acc_vl_find_index(vni->access_vlan, br_ifindex); if (!acc_bd) return; diff --git a/zebra/zebra_evpn_mh.h b/zebra/zebra_evpn_mh.h index 6dda30a57f..59a41d0606 100644 --- a/zebra/zebra_evpn_mh.h +++ b/zebra/zebra_evpn_mh.h @@ -344,6 +344,8 @@ extern void zebra_evpn_if_es_print(struct vty *vty, json_object *json, struct zebra_if *zif); extern struct zebra_evpn_access_bd * zebra_evpn_acc_vl_find(vlanid_t vid, struct interface *br_if); +struct zebra_evpn_access_bd * +zebra_evpn_acc_vl_find_index(vlanid_t vid, ifindex_t bridge_ifindex); extern void zebra_evpn_acc_vl_show_vid(struct vty *vty, bool uj, vlanid_t vid, struct interface *br_if); extern void zebra_evpn_es_cleanup(void); -- 2.39.5