aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2024-04-24 02:09:56 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2024-04-24 02:11:25 +0200
commitd3963e92499f3d71a213975480030e74ea73a774 (patch)
tree66865c6be1dc4f8a1ce5b359eebca7dfaad0311c /src
parentd0158bf4cab929d4143a78d4c992cf271bf264e0 (diff)
downloadslirp-d3963e92499f3d71a213975480030e74ea73a774.zip
slirp-d3963e92499f3d71a213975480030e74ea73a774.tar.gz
slirp-d3963e92499f3d71a213975480030e74ea73a774.tar.bz2
m_cleanup_list: Fix missing cleanup packets from the same session
When several packets are queued for emission for the same socket session, we need to clean them all. Spotted thanks to ASAN & fuzzing. Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Diffstat (limited to 'src')
-rw-r--r--src/if.c6
-rw-r--r--src/mbuf.c37
-rw-r--r--src/mbuf.h6
3 files changed, 33 insertions, 16 deletions
diff --git a/src/if.c b/src/if.c
index 6b365ce..c666ad8 100644
--- a/src/if.c
+++ b/src/if.c
@@ -13,12 +13,6 @@ static void ifs_insque(struct mbuf *ifm, struct mbuf *ifmhead)
ifm->ifs_next->ifs_prev = ifm;
}
-static void ifs_remque(struct mbuf *ifm)
-{
- ifm->ifs_prev->ifs_next = ifm->ifs_next;
- ifm->ifs_next->ifs_prev = ifm->ifs_prev;
-}
-
void if_init(Slirp *slirp)
{
slirp->if_fastq.qh_link = slirp->if_fastq.qh_rlink = &slirp->if_fastq;
diff --git a/src/mbuf.c b/src/mbuf.c
index 6fa4065..400c19f 100644
--- a/src/mbuf.c
+++ b/src/mbuf.c
@@ -29,17 +29,34 @@ void m_init(Slirp *slirp)
slirp->m_usedlist.qh_link = slirp->m_usedlist.qh_rlink = &slirp->m_usedlist;
}
-static void m_cleanup_list(struct slirp_quehead *list_head)
+static void m_cleanup_list(struct slirp_quehead *list_head, bool pkts)
{
- struct mbuf *m, *next;
+ struct mbuf *m, *next, *next2;
+ bool last;
m = (struct mbuf *)list_head->qh_link;
while ((struct slirp_quehead *)m != list_head) {
next = m->m_next;
- if (m->m_flags & M_EXT) {
- g_free(m->m_ext);
- }
- g_free(m);
+
+ last = false;
+ do {
+ next2 = m->ifs_next;
+
+ if (pkts) {
+ ifs_remque(m);
+ last = next2 == m;
+ } else {
+ last = true;
+ }
+
+ if (m->m_flags & M_EXT) {
+ g_free(m->m_ext);
+ }
+
+ g_free(m);
+ m = next2;
+ } while (!last);
+
m = next;
}
list_head->qh_link = list_head;
@@ -48,10 +65,10 @@ static void m_cleanup_list(struct slirp_quehead *list_head)
void m_cleanup(Slirp *slirp)
{
- m_cleanup_list(&slirp->m_usedlist);
- m_cleanup_list(&slirp->m_freelist);
- m_cleanup_list(&slirp->if_batchq);
- m_cleanup_list(&slirp->if_fastq);
+ m_cleanup_list(&slirp->m_usedlist, false);
+ m_cleanup_list(&slirp->m_freelist, false);
+ m_cleanup_list(&slirp->if_batchq, true);
+ m_cleanup_list(&slirp->if_fastq, true);
}
/*
diff --git a/src/mbuf.h b/src/mbuf.h
index d73ce3f..05be495 100644
--- a/src/mbuf.h
+++ b/src/mbuf.h
@@ -109,6 +109,12 @@ struct mbuf {
#define ifs_next m_nextpkt
#define ifq_so m_so
+static inline void ifs_remque(struct mbuf *ifm)
+{
+ ifm->ifs_prev->ifs_next = ifm->ifs_next;
+ ifm->ifs_next->ifs_prev = ifm->ifs_prev;
+}
+
#define M_EXT 0x01 /* m_ext points to more (malloced) data */
#define M_FREELIST 0x02 /* mbuf is on free list */
#define M_USEDLIST 0x04 /* XXX mbuf is on used list (for dtom()) */