From 64d4a3f945b25792a44ef8b561f9874a3de5caeb Mon Sep 17 00:00:00 2001 From: mpi Date: Mon, 15 Jun 2015 15:55:08 +0000 Subject: [PATCH] Fix a double free in the destroy path triggered when a second process, in my case dhclient(8), races with ifconfig(8) to free the descriptors of the joined multicast groups. While here reduce the difference with carp(4). ok dms@ --- sys/net/if_trunk.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/sys/net/if_trunk.c b/sys/net/if_trunk.c index 32d23f258c5..5de66dd6e3e 100644 --- a/sys/net/if_trunk.c +++ b/sys/net/if_trunk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_trunk.c,v 1.101 2015/06/09 14:50:14 mpi Exp $ */ +/* $OpenBSD: if_trunk.c,v 1.102 2015/06/15 15:55:08 mpi Exp $ */ /* * Copyright (c) 2005, 2006, 2007 Reyk Floeter @@ -857,18 +857,20 @@ trunk_ether_delmulti(struct trunk_softc *tr, struct ifreq *ifr) if ((error = ether_delmulti(ifr, &tr->tr_ac)) != ENETRESET) return (error); - if ((error = trunk_ioctl_allports(tr, SIOCDELMULTI, - (caddr_t)ifr)) != 0) { + /* We no longer use this multicast address. Tell parent so. */ + error = trunk_ioctl_allports(tr, SIOCDELMULTI, (caddr_t)ifr); + if (error == 0) { + SLIST_REMOVE(&tr->tr_mc_head, mc, trunk_mc, mc_entries); + free(mc, M_DEVBUF, sizeof(*mc)); + } else { /* XXX At least one port failed to remove the address */ if (tr->tr_ifflags & IFF_DEBUG) { printf("%s: failed to remove multicast address " - "on all ports\n", tr->tr_ifname); + "on all ports (%d)\n", tr->tr_ifname, error); } + (void)ether_addmulti(ifr, &tr->tr_ac); } - SLIST_REMOVE(&tr->tr_mc_head, mc, trunk_mc, mc_entries); - free(mc, M_DEVBUF, 0); - return (0); } @@ -886,7 +888,7 @@ trunk_ether_purgemulti(struct trunk_softc *tr) trunk_ioctl_allports(tr, SIOCDELMULTI, (caddr_t)ifr); SLIST_REMOVE(&tr->tr_mc_head, mc, trunk_mc, mc_entries); - free(mc, M_DEVBUF, 0); + free(mc, M_DEVBUF, sizeof(*mc)); } } -- 2.20.1