aboutsummaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorBjoern A. Zeeb <bz@FreeBSD.org>2010-04-11 18:41:31 +0000
committerBjoern A. Zeeb <bz@FreeBSD.org>2010-04-11 18:41:31 +0000
commitc769e1be01799e8f413f6b5151cbe4f4860d67f3 (patch)
tree5e7428262cc4961f28340102167c5ba10af773f1 /sys/net
parent43c3bf3cc642300813fa2728fef3d31ba7518735 (diff)
downloadsrc-c769e1be01799e8f413f6b5151cbe4f4860d67f3.tar.gz
src-c769e1be01799e8f413f6b5151cbe4f4860d67f3.zip
Check that the interface is on the list of cloned interfaces before trying
to remove it to avoid panics in case of two threads trying to remove it in parallel. PR: kern/116837 Submitted by: Takahiro Kurosawa (takahiro.kurosawa gmail.com) (orig version) MFC after: 10 days
Notes
Notes: svn path=/head/; revision=206486
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/if_clone.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/sys/net/if_clone.c b/sys/net/if_clone.c
index 0dd20fb36108..81ac7ffbdba5 100644
--- a/sys/net/if_clone.c
+++ b/sys/net/if_clone.c
@@ -234,6 +234,7 @@ int
if_clone_destroyif(struct if_clone *ifc, struct ifnet *ifp)
{
int err;
+ struct ifnet *ifcifp;
if (ifc->ifc_destroy == NULL)
return(EOPNOTSUPP);
@@ -246,8 +247,17 @@ if_clone_destroyif(struct if_clone *ifc, struct ifnet *ifp)
CURVNET_SET_QUIET(ifp->if_vnet);
IF_CLONE_LOCK(ifc);
- IFC_IFLIST_REMOVE(ifc, ifp);
+ LIST_FOREACH(ifcifp, &ifc->ifc_iflist, if_clones) {
+ if (ifcifp == ifp) {
+ IFC_IFLIST_REMOVE(ifc, ifp);
+ break;
+ }
+ }
IF_CLONE_UNLOCK(ifc);
+ if (ifcifp == NULL) {
+ CURVNET_RESTORE();
+ return (ENXIO); /* ifp is not on the list. */
+ }
if_delgroup(ifp, ifc->ifc_name);