summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgonzo <gonzo@FreeBSD.org>2008-06-24 13:58:28 +0000
committergonzo <gonzo@FreeBSD.org>2008-06-24 13:58:28 +0000
commitafeaa2fd28e4e54ef4c528193706bd6c4d462788 (patch)
tree63ede7b43865e98e46107d9ac9c305797edd0dd6
parent70dd244f261431949d544de710e4401a0ef0f237 (diff)
downloadFreeBSD-src-afeaa2fd28e4e54ef4c528193706bd6c4d462788.zip
FreeBSD-src-afeaa2fd28e4e54ef4c528193706bd6c4d462788.tar.gz
In case of interface initialization failure remove struct in_ifaddr* from
in_ifaddrhashtbl in in_ifinit because error handler in in_control removes entries only for AF_INET addresses. If in_ifinit is called for the cloned inteface that has just been created its address family is not AF_INET and therefor LIST_REMOVE is not called for respective LIST_INSERT_HEAD and freed entries remain in in_ifaddrhashtbl and lead to memory corruption. PR: kern/124384
-rw-r--r--sys/netinet/in.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index a6801b9..4c74b07 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -734,6 +734,14 @@ in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin,
if (ia->ia_addr.sin_family == AF_INET)
LIST_INSERT_HEAD(INADDR_HASH(
ia->ia_addr.sin_addr.s_addr), ia, ia_hash);
+ else
+ /*
+ * If oldaddr family is not AF_INET (e.g.
+ * interface has been just created) in_control
+ * does not call LIST_REMOVE, and we end up
+ * with bogus ia entries in hash
+ */
+ LIST_REMOVE(ia, ia_hash);
return (error);
}
}
OpenPOWER on IntegriCloud