diff options
author | Pooja Jagadeesh Doijode <pdoijode@nvidia.com> | 2023-03-20 20:54:31 +0100 |
---|---|---|
committer | Pooja Jagadeesh Doijode <pdoijode@nvidia.com> | 2023-03-20 20:54:31 +0100 |
commit | 7eefea98ba5d42dc3f042b509fe0f18a0e1d5548 (patch) | |
tree | c1171a79ecb6f30ea91efd5639ab9707045b4fde /zebra | |
parent | Merge pull request #13050 from opensourcerouting/fix/update_snmp_mibs_doc (diff) | |
download | frr-7eefea98ba5d42dc3f042b509fe0f18a0e1d5548.tar.xz frr-7eefea98ba5d42dc3f042b509fe0f18a0e1d5548.zip |
zebra: Fix for heap-use-after-free in EVPN
Issue:
When a netns is deleted, since zebra doesn’t receive interface down/delete
notifications from kernel, it manually deletes the interface without removing
the association between zebra_l3vni and the interface that is being deleted
(i.e it deletes the interface without setting “zl3vni->vxlan_if” to NULL).
Later, during the deletion of netns, when zl3vni_rmac_uninstall() is called to
uninstall the remote RMAC from the kernel, zebra ends up accessing stale
“zl3vni->vxlan_if” pointer, which now points to freed memory.
This was causing heap use-after-free.
Fix:
Before zebra starts deleting the interfaces when it receives netns delete notification,
appropriate functions() are being called to remove the association between evpn structs
and interface and set “zl3vni->vxlan_if” to NULL. This ensures that when
zl3vni_rmac_uninstall() is called during netns deletion, it will bail because
“zl3vni->vxlan_if” is NULL.
Signed-off-by: Pooja Jagadeesh Doijode <pdoijode@nvidia.com>
Diffstat (limited to 'zebra')
-rw-r--r-- | zebra/zebra_netns_notify.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/zebra/zebra_netns_notify.c b/zebra/zebra_netns_notify.c index cdba0c21a..28f3c03ab 100644 --- a/zebra/zebra_netns_notify.c +++ b/zebra/zebra_netns_notify.c @@ -165,6 +165,17 @@ static int zebra_ns_delete(char *name) if_down(ifp); } + if (IS_ZEBRA_IF_BOND(ifp)) + zebra_l2if_update_bond(ifp, false); + if (IS_ZEBRA_IF_BOND_SLAVE(ifp)) + zebra_l2if_update_bond_slave(ifp, IFINDEX_INTERNAL, + false); + /* Special handling for bridge or VxLAN interfaces. */ + if (IS_ZEBRA_IF_BRIDGE(ifp)) + zebra_l2_bridge_del(ifp); + else if (IS_ZEBRA_IF_VXLAN(ifp)) + zebra_l2_vxlanif_del(ifp); + UNSET_FLAG(ifp->flags, IFF_UP); if_delete_update(&ifp); } |