FreeBSD Bugzilla – Attachment 200658 Details for
Bug 233535
Fix refcount leak in IPv6 MLD code leading to loss of IPv6 connectivity
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Fix missing decrement of refcount in IPv6 code (w/ additional debug code)
in6_multi.diff (text/plain), 3.67 KB, created by
Hans Petter Selasky
on 2018-12-31 15:02:16 UTC
(
hide
)
Description:
Fix missing decrement of refcount in IPv6 code (w/ additional debug code)
Filename:
MIME Type:
Creator:
Hans Petter Selasky
Created:
2018-12-31 15:02:16 UTC
Size:
3.67 KB
patch
obsolete
>Index: sys/netinet6/in6_mcast.c >=================================================================== >--- sys/netinet6/in6_mcast.c (revision 342455) >+++ sys/netinet6/in6_mcast.c (working copy) >@@ -426,6 +426,7 @@ > * If we already joined this group, just bump the > * refcount and return it. > */ >+ hptrace(inm, "check"); > KASSERT(inm->in6m_refcount >= 1, > ("%s: bad refcount %d", __func__, inm->in6m_refcount)); > in6m_acquire_locked(inm); >@@ -497,6 +498,7 @@ > inm->in6m_mli = MLD_IFINFO(ifp); > inm->in6m_ifma = ifma; > inm->in6m_refcount = 1; >+ hptrace(inm, "set"); > inm->in6m_state = MLD_NOT_MEMBER; > mbufq_init(&inm->in6m_scq, MLD_MAX_STATE_CHANGES); > >@@ -527,6 +529,8 @@ > > CTR2(KTR_MLD, "%s: refcount is %d", __func__, inm->in6m_refcount); > >+ hptrace(inm, "check"); >+ > MPASS(inm->in6m_refcount == 0); > CTR2(KTR_MLD, "%s: freeing inm %p", __func__, inm); > >@@ -632,6 +636,9 @@ > i6mm_chain, imm_tmp) { > if (inm == imm->i6mm_maddr) { > LIST_REMOVE(imm, i6mm_chain); >+ inm->in6m_refcount--; >+ hptrace(inm, "list remove - post dec"); >+ MPASS(inm->in6m_refcount > 0); > free(imm, M_IP6MADDR); > } > } >@@ -646,6 +653,7 @@ > IN6_MULTI_LIST_LOCK_ASSERT(); > KASSERT(inm->in6m_refcount > 0, ("refcount == %d inm: %p", inm->in6m_refcount, inm)); > if (--inm->in6m_refcount == 0) { >+ hptrace(inm, "list release - post dec"); > MPASS(inm->in6m_ifp == NULL); > SLIST_INIT(&tmp); > inm->in6m_ifma->ifma_protospec = NULL; >@@ -652,6 +660,8 @@ > MPASS(inm->in6m_ifma->ifma_llifma == NULL); > SLIST_INSERT_HEAD(&tmp, inm, in6m_nrele); > in6m_release_list_deferred(&tmp); >+ } else { >+ hptrace(inm, "list release - post dec"); > } > } > >@@ -1413,6 +1423,8 @@ > CTR2(KTR_MLD, "%s: dropping ref on %p", __func__, inm); > if (ifp) > IF_ADDR_WLOCK(ifp); >+ >+ hptrace(inm, "leavegroup check"); > if (inm->in6m_refcount == 1 && inm->in6m_ifp != NULL) > in6m_disconnect(inm); > in6m_release_deferred(inm); >Index: sys/netinet6/in6_var.h >=================================================================== >--- sys/netinet6/in6_var.h (revision 342455) >+++ sys/netinet6/in6_var.h (working copy) >@@ -760,6 +760,15 @@ > return (inm); > } > >+#include <sys/kdb.h> >+ >+static inline void >+hptrace(struct in6_multi *inm, const char *msg) >+{ >+ printf("%s - in6m_refcount = %d\n", msg, inm->in6m_refcount); >+ kdb_backtrace(); >+} >+ > /* Acquire an in6_multi record. */ > static __inline void > in6m_acquire_locked(struct in6_multi *inm) >@@ -767,6 +776,7 @@ > > IN6_MULTI_LIST_LOCK_ASSERT(); > ++inm->in6m_refcount; >+ hptrace(inm, "acquire_locked - post inc"); > } > > static __inline void >@@ -784,10 +794,13 @@ > IN6_MULTI_LIST_LOCK_ASSERT(); > > if (--inm->in6m_refcount == 0) { >+ hptrace(inm, "rele_locked - post dec"); > MPASS(inm->in6m_ifp == NULL); > inm->in6m_ifma->ifma_protospec = NULL; > MPASS(inm->in6m_ifma->ifma_llifma == NULL); > SLIST_INSERT_HEAD(inmh, inm, in6m_nrele); >+ } else { >+ hptrace(inm, "rele_locked - post dec"); > } > } > >Index: sys/netinet6/mld6.c >=================================================================== >--- sys/netinet6/mld6.c (revision 342455) >+++ sys/netinet6/mld6.c (working copy) >@@ -1895,6 +1895,14 @@ > error = 0; > > /* >+ * Check if the in6_multi has already been disconnected. >+ */ >+ if (inm->in6m_ifp == NULL) { >+ CTR3(KTR_MLD, "%s: inm is disconnected", __func__); >+ return (0); >+ } >+ >+ /* > * Try to detect if the upper layer just asked us to change state > * for an interface which has now gone away. > */ >@@ -2004,6 +2012,8 @@ > if (mli->mli_version == MLD_VERSION_2 && > inm->in6m_state == MLD_LEAVING_MEMBER) { > inm->in6m_refcount--; >+ hptrace(inm, "leaving member - post dec"); >+ MPASS(inm->in6m_refcount > 0); > } > inm->in6m_state = MLD_REPORTING_MEMBER; >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 233535
:
200199
|
200658
|
200699
|
200753
|
200887
|
200956
|
201125
|
201210
|
201211
|
201212
|
201220
|
201221
|
201228