qemu/0003-slirp-Fix-requeuing-of-batchq-packets-in-if_start.patch
Cole Robinson dee28d805f Remove comma from 1.0.1 version number
CVE-2012-3515 VT100 emulation vulnerability (bz #854600, bz 851252)
Fix slirp crash (bz #845793)
Fix KVM module permissions after install (bz #863374)
2012-10-07 16:24:18 -04:00

96 lines
3.0 KiB
Diff

From 3c5ff5a0a14a2cd7098560f5637bd945cac7f17b Mon Sep 17 00:00:00 2001
Message-Id: <3c5ff5a0a14a2cd7098560f5637bd945cac7f17b.1349639034.git.crobinso@redhat.com>
In-Reply-To: <be94aaec72dbacd0d948946ebab482864454b8ff.1349639034.git.crobinso@redhat.com>
References: <be94aaec72dbacd0d948946ebab482864454b8ff.1349639034.git.crobinso@redhat.com>
From: Jan Kiszka <jan.kiszka@siemens.com>
Date: Fri, 17 Feb 2012 16:26:38 +0100
Subject: [PATCH 3/3] slirp: Fix requeuing of batchq packets in if_start
In case we requeued a packet that was the head of a longer session
queue, we failed to restore this ordering. Also, we did not properly
deal with changes to Slirp::next_m.
Instead of a cumbersome roll back, this fix simply avoids any changes
until we know if the packet was actually sent. Both fixes crashes due
to inconsistent queues and simplifies the logic.
Thanks to Zhi Yong Wu who found the reason for these crashes.
CC: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
CC: Fabien Chouteau <chouteau@adacore.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
(cherry picked from commit b248ede2ef2792d364bd305e5e92e24921c924a8)
Signed-off-by: Cole Robinson <crobinso@redhat.com>
---
slirp/if.c | 35 +++++++++++++++++++----------------
1 file changed, 19 insertions(+), 16 deletions(-)
diff --git a/slirp/if.c b/slirp/if.c
index 2852396..75a3c26 100644
--- a/slirp/if.c
+++ b/slirp/if.c
@@ -156,6 +156,7 @@ if_start(Slirp *slirp)
{
uint64_t now = qemu_get_clock_ns(rt_clock);
int requeued = 0;
+ bool from_batchq = false;
struct mbuf *ifm, *ifqt;
DEBUG_CALL("if_start");
@@ -181,13 +182,26 @@ if_start(Slirp *slirp)
else
ifm = slirp->if_batchq.ifq_next;
- /* Set which packet to send on next iteration */
- slirp->next_m = ifm->ifq_next;
+ from_batchq = true;
}
+
+ slirp->if_queued--;
+
+ /* Try to send packet unless it already expired */
+ if (ifm->expiration_date >= now && !if_encap(slirp, ifm)) {
+ /* Packet is delayed due to pending ARP resolution */
+ requeued++;
+ goto out;
+ }
+
+ if (from_batchq) {
+ /* Set which packet to send on next iteration */
+ slirp->next_m = ifm->ifq_next;
+ }
+
/* Remove it from the queue */
ifqt = ifm->ifq_prev;
remque(ifm);
- slirp->if_queued--;
/* If there are more packets for this session, re-queue them */
if (ifm->ifs_next != /* ifm->ifs_prev != */ ifm) {
@@ -202,20 +216,9 @@ if_start(Slirp *slirp)
ifm->ifq_so->so_nqueued = 0;
}
- if (ifm->expiration_date < now) {
- /* Expired */
- m_free(ifm);
- } else {
- /* Encapsulate the packet for sending */
- if (if_encap(slirp, ifm)) {
- m_free(ifm);
- } else {
- /* re-queue */
- insque(ifm, ifqt);
- requeued++;
- }
- }
+ m_free(ifm);
+ out:
if (slirp->if_queued)
goto again;
--
1.7.11.4