From c98bed60cdd7f22237ae256cc9c1c3087206b8a2 Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Tue, 15 Feb 2022 01:42:00 +0200 Subject: [PATCH] net: mscc: ocelot: fix use-after-free in ocelot_vlan_del() commit ef57640575406f57f5b3393cf57f457b0ace837e upstream. ocelot_vlan_member_del() will free the struct ocelot_bridge_vlan, so if this is the same as the port's pvid_vlan which we access afterwards, what we're accessing is freed memory. Fix the bug by determining whether to clear ocelot_port->pvid_vlan prior to calling ocelot_vlan_member_del(). Fixes: d4004422f6f9 ("net: mscc: ocelot: track the port pvid using a pointer") Signed-off-by: Vladimir Oltean Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ethernet/mscc/ocelot.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c index 02edd383dea22..886daa29bfb02 100644 --- a/drivers/net/ethernet/mscc/ocelot.c +++ b/drivers/net/ethernet/mscc/ocelot.c @@ -480,14 +480,18 @@ EXPORT_SYMBOL(ocelot_vlan_add); int ocelot_vlan_del(struct ocelot *ocelot, int port, u16 vid) { struct ocelot_port *ocelot_port = ocelot->ports[port]; + bool del_pvid = false; int err; + if (ocelot_port->pvid_vlan && ocelot_port->pvid_vlan->vid == vid) + del_pvid = true; + err = ocelot_vlan_member_del(ocelot, port, vid); if (err) return err; /* Ingress */ - if (ocelot_port->pvid_vlan && ocelot_port->pvid_vlan->vid == vid) + if (del_pvid) ocelot_port_set_pvid(ocelot, port, NULL); /* Egress */