yeahuh / rpms / qemu-kvm

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