summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPooja Jagadeesh Doijode <pdoijode@nvidia.com>2023-03-20 12:54:31 -0700
committerMergify <37929162+mergify[bot]@users.noreply.github.com>2023-03-21 11:05:09 +0000
commite24c7991384a2e871c91a8ece5cc2324f32b0170 (patch)
treee96e2a5863e06feb2836a71f691c11464f7f2f3f
parent8d2666fb039f8aac1f8f8a4ece92a2f4bf03200f (diff)
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> (cherry picked from commit 7eefea98ba5d42dc3f042b509fe0f18a0e1d5548)
-rw-r--r--zebra/zebra_netns_notify.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/zebra/zebra_netns_notify.c b/zebra/zebra_netns_notify.c
index 50b7ff9233..22e5c1fca3 100644
--- a/zebra/zebra_netns_notify.c
+++ b/zebra/zebra_netns_notify.c
@@ -178,6 +178,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);
}