diff options
| author | Mark Johnston <markj@FreeBSD.org> | 2026-05-12 17:53:49 +0000 |
|---|---|---|
| committer | Mark Johnston <markj@FreeBSD.org> | 2026-05-12 20:05:19 +0000 |
| commit | beab4a237a45aea809e81802b9e1e9ff30f3d929 (patch) | |
| tree | f04fa8f54576952d2fc1042502727941aac13bd7 | |
| parent | a6c4fe2d1a38885914b1c3e85508b965ccdb7874 (diff) | |
igmp: Avoid leaving dangling pointers in the state-change queue
When igmp_v3_merge_state_changes() is iterating over state-change
packets, there is a case where it'll free a queued packet but will fail
to remove it from the queue. Fix that.
Reported by: Yuxiang Yang, Yizhou Zhao, Xuewei Feng, Qi Li, and Ke Xu from Tsinghua University using GLM5.1 from Z.ai
Reviewed by: pouria, glebius
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D56947
| -rw-r--r-- | sys/netinet/igmp.c | 8 | ||||
| -rw-r--r-- | sys/sys/mbuf.h | 8 |
2 files changed, 13 insertions, 3 deletions
diff --git a/sys/netinet/igmp.c b/sys/netinet/igmp.c index 00288356cb1f..226f38a035fb 100644 --- a/sys/netinet/igmp.c +++ b/sys/netinet/igmp.c @@ -3326,10 +3326,12 @@ igmp_v3_merge_state_changes(struct in_multi *inm, struct mbufq *scq) CTR2(KTR_IGMPV3, "%s: outbound queue full, skipping whole packet %p", __func__, m); - mt = m->m_nextpkt; - if (!docopy) + m0 = m->m_nextpkt; + if (!docopy) { + mbufq_remove(gq, m); m_freem(m); - m = mt; + } + m = m0; continue; } diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h index c5072cec904b..fb1a0a5b81d0 100644 --- a/sys/sys/mbuf.h +++ b/sys/sys/mbuf.h @@ -1656,6 +1656,14 @@ mbufq_enqueue(struct mbufq *mq, struct mbuf *m) return (0); } +static inline void +mbufq_remove(struct mbufq *mq, struct mbuf *m) +{ + + STAILQ_REMOVE(&mq->mq_head, m, mbuf, m_stailqpkt); + mq->mq_len--; +} + static inline struct mbuf * mbufq_dequeue(struct mbufq *mq) { |
