|
|
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 |
|