893208
From fc0bca7bd2685b8f8e3c37f19ce74967870ef952 Mon Sep 17 00:00:00 2001
893208
From: Jon Maloy <jmaloy@redhat.com>
893208
Date: Thu, 21 Oct 2021 12:10:47 -0400
893208
Subject: [PATCH 2/2] e1000: fix tx re-entrancy problem
893208
MIME-Version: 1.0
893208
Content-Type: text/plain; charset=UTF-8
893208
Content-Transfer-Encoding: 8bit
893208
893208
RH-Author: Jon Maloy <jmaloy@redhat.com>
893208
RH-MergeRequest: 73: e1000: fix tx re-entrancy problem
893208
RH-Commit: [1/1] 3088ea275ddcee1ba0d47f7cff195af3e256f15f (jmaloy/qemu-kvm)
893208
RH-Bugzilla: 2025011
893208
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
893208
RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
893208
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
893208
893208
The fact that the MMIO handler is not re-entrant causes an infinite
893208
loop under certain conditions:
893208
893208
Guest write to TDT ->  Loopback -> RX (DMA to TDT) -> TX
893208
893208
We now eliminate the effect of this problem locally in e1000, by adding
893208
a boolean in struct E1000State indicating when the TX side is busy. This
893208
will cause any entering new call to return early instead of interfering
893208
with the ongoing work, and eliminates any risk of looping.
893208
893208
This is intended to address CVE-2021-20257.
893208
893208
Signed-off-by: Jon Maloy <jmaloy@redhat.com>
893208
Signed-off-by: Jason Wang <jasowang@redhat.com>
893208
(cherry picked from commit 25ddb946e6301f42cff3094ea1c25fb78813e7e9)
893208
Signed-off-by: Jon Maloy <jmaloy@redhat.com>
893208
---
893208
 hw/net/e1000.c | 7 +++++++
893208
 1 file changed, 7 insertions(+)
893208
893208
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
893208
index 8680b7d46b..1963a5b243 100644
893208
--- a/hw/net/e1000.c
893208
+++ b/hw/net/e1000.c
893208
@@ -105,6 +105,7 @@ typedef struct E1000State_st {
893208
         e1000x_txd_props props;
893208
         e1000x_txd_props tso_props;
893208
         uint16_t tso_frames;
893208
+        bool busy;
893208
     } tx;
893208
 
893208
     struct {
893208
@@ -749,6 +750,11 @@ start_xmit(E1000State *s)
893208
         return;
893208
     }
893208
 
893208
+    if (s->tx.busy) {
893208
+        return;
893208
+    }
893208
+    s->tx.busy = true;
893208
+
893208
     while (s->mac_reg[TDH] != s->mac_reg[TDT]) {
893208
         base = tx_desc_base(s) +
893208
                sizeof(struct e1000_tx_desc) * s->mac_reg[TDH];
893208
@@ -775,6 +781,7 @@ start_xmit(E1000State *s)
893208
             break;
893208
         }
893208
     }
893208
+    s->tx.busy = false;
893208
     set_ics(s, 0, cause);
893208
 }
893208
 
893208
-- 
893208
2.27.0
893208