svn commit: r343394 - head/sys/netinet6
Hans Petter Selasky
hselasky at FreeBSD.org
Thu Jan 24 08:25:04 UTC 2019
Author: hselasky
Date: Thu Jan 24 08:25:02 2019
New Revision: 343394
URL: https://svnweb.freebsd.org/changeset/base/343394
Log:
When detaching a network interface drain the workqueue freeing the inm's
because the destructor will access the if_ioctl() callback in the ifnet
pointer which is about to be freed. This prevents use-after-free.
PR: 233535
Differential Revision: https://reviews.freebsd.org/D18887
Reviewed by: bz (net)
Tested by: ae
MFC after: 1 week
Sponsored by: Mellanox Technologies
Modified:
head/sys/netinet6/in6_ifattach.c
head/sys/netinet6/in6_mcast.c
head/sys/netinet6/in6_var.h
Modified: head/sys/netinet6/in6_ifattach.c
==============================================================================
--- head/sys/netinet6/in6_ifattach.c Thu Jan 24 08:18:02 2019 (r343393)
+++ head/sys/netinet6/in6_ifattach.c Thu Jan 24 08:25:02 2019 (r343394)
@@ -884,6 +884,13 @@ in6_purgemaddrs(struct ifnet *ifp)
IN6_MULTI_LIST_UNLOCK();
IN6_MULTI_UNLOCK();
in6m_release_list_deferred(&purgeinms);
+
+ /*
+ * Make sure all multicast deletions invoking if_ioctl() are
+ * completed before returning. Else we risk accessing a freed
+ * ifnet structure pointer.
+ */
+ in6m_release_wait();
}
void
Modified: head/sys/netinet6/in6_mcast.c
==============================================================================
--- head/sys/netinet6/in6_mcast.c Thu Jan 24 08:18:02 2019 (r343393)
+++ head/sys/netinet6/in6_mcast.c Thu Jan 24 08:25:02 2019 (r343394)
@@ -585,6 +585,14 @@ in6m_release_list_deferred(struct in6_multi_head *inmh
}
void
+in6m_release_wait(void)
+{
+
+ /* Wait for all jobs to complete. */
+ gtaskqueue_drain_all(free_gtask.gt_taskqueue);
+}
+
+void
in6m_disconnect(struct in6_multi *inm)
{
struct ifnet *ifp;
Modified: head/sys/netinet6/in6_var.h
==============================================================================
--- head/sys/netinet6/in6_var.h Thu Jan 24 08:18:02 2019 (r343393)
+++ head/sys/netinet6/in6_var.h Thu Jan 24 08:25:02 2019 (r343394)
@@ -811,6 +811,7 @@ void in6m_print(const struct in6_multi *);
int in6m_record_source(struct in6_multi *, const struct in6_addr *);
void in6m_release_deferred(struct in6_multi *);
void in6m_release_list_deferred(struct in6_multi_head *);
+void in6m_release_wait(void);
void ip6_freemoptions(struct ip6_moptions *);
int ip6_getmoptions(struct inpcb *, struct sockopt *);
int ip6_setmoptions(struct inpcb *, struct sockopt *);
More information about the svn-src-all
mailing list