54 lines
1.9 KiB
Diff
54 lines
1.9 KiB
Diff
From c2e03e2aa42d0f4f41deb08c2655503835840afa Mon Sep 17 00:00:00 2001
|
|
From: Michael Roth <mdroth@linux.vnet.ibm.com>
|
|
Date: Tue, 24 Sep 2019 15:57:59 -0500
|
|
Subject: [PATCH] slirp: Fix heap overflow in ip_reass on big packet input
|
|
|
|
When the first fragment does not fit in the preallocated buffer, q will
|
|
already be pointing to the ext buffer, so we mustn't try to update it.
|
|
|
|
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
|
|
(from libslirp.git commit 126c04acbabd7ad32c2b018fe10dfac2a3bc1210)
|
|
(from libslirp.git commit e0be80430c390bce181ea04dfcdd6ea3dfa97de1)
|
|
*squash in e0be80 (clarifying comments)
|
|
Fixes: CVE-2019-14378
|
|
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
|
|
---
|
|
slirp/src/ip_input.c | 13 +++++++------
|
|
1 file changed, 7 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/slirp/src/ip_input.c b/slirp/src/ip_input.c
|
|
index a714fecd58..68a99de5b5 100644
|
|
--- a/slirp/src/ip_input.c
|
|
+++ b/slirp/src/ip_input.c
|
|
@@ -331,6 +331,8 @@ insert:
|
|
q = fp->frag_link.next;
|
|
m = dtom(slirp, q);
|
|
|
|
+ int was_ext = m->m_flags & M_EXT;
|
|
+
|
|
q = (struct ipasfrag *) q->ipf_next;
|
|
while (q != (struct ipasfrag*)&fp->frag_link) {
|
|
struct mbuf *t = dtom(slirp, q);
|
|
@@ -347,13 +349,12 @@ insert:
|
|
q = fp->frag_link.next;
|
|
|
|
/*
|
|
- * If the fragments concatenated to an mbuf that's
|
|
- * bigger than the total size of the fragment, then and
|
|
- * m_ext buffer was alloced. But fp->ipq_next points to
|
|
- * the old buffer (in the mbuf), so we must point ip
|
|
- * into the new buffer.
|
|
+ * If the fragments concatenated to an mbuf that's bigger than the total
|
|
+ * size of the fragment and the mbuf was not already using an m_ext buffer,
|
|
+ * then an m_ext buffer was alloced. But fp->ipq_next points to the old
|
|
+ * buffer (in the mbuf), so we must point ip into the new buffer.
|
|
*/
|
|
- if (m->m_flags & M_EXT) {
|
|
+ if (!was_ext && m->m_flags & M_EXT) {
|
|
int delta = (char *)q - m->m_dat;
|
|
q = (struct ipasfrag *)(m->m_ext + delta);
|
|
}
|
|
--
|
|
2.19.1
|
|
|