]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: Fix for heap-use-after-free in EVPN 13062/head
authorPooja Jagadeesh Doijode <pdoijode@nvidia.com>
Mon, 20 Mar 2023 19:54:31 +0000 (12:54 -0700)
committerPooja Jagadeesh Doijode <pdoijode@nvidia.com>
Mon, 20 Mar 2023 19:54:31 +0000 (12:54 -0700)
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>
zebra/zebra_netns_notify.c

index cdba0c21aba9a53c003842033f9a13196a0492f6..28f3c03abea845c63343bebf1a3fe75e2b3f8000 100644 (file)
@@ -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);
        }