[PULL V2 04/20] e1000: fail early for evil descriptor

Jason Wang posted 20 patches 4 years ago
Maintainers: Jason Wang <jasowang@redhat.com>, "Michael S. Tsirkin" <mst@redhat.com>, Giuseppe Lettieri <g.lettieri@iet.unipi.it>, Anthony Perard <anthony.perard@citrix.com>, Luigi Rizzo <rizzo@iet.unipi.it>, Paul Durrant <paul@xen.org>, Stefano Stabellini <sstabellini@kernel.org>, Thomas Huth <thuth@redhat.com>, Samuel Thibault <samuel.thibault@ens-lyon.org>, Markus Armbruster <armbru@redhat.com>, Michael Roth <michael.roth@amd.com>, Yuval Shaia <yuval.shaia.ml@gmail.com>, Vincenzo Maffione <v.maffione@gmail.com>, Marcel Apfelbaum <marcel.apfelbaum@gmail.com>, Laurent Vivier <lvivier@redhat.com>, Eric Blake <eblake@redhat.com>, Paolo Bonzini <pbonzini@redhat.com>, Cornelia Huck <cohuck@redhat.com>, Stefan Weil <sw@weilnetz.de>
There is a newer version of this series
[PULL V2 04/20] e1000: fail early for evil descriptor
Posted by Jason Wang 4 years ago
During procss_tx_desc(), driver can try to chain data descriptor with
legacy descriptor, when will lead underflow for the following
calculation in process_tx_desc() for bytes:

            if (tp->size + bytes > msh)
                bytes = msh - tp->size;

This will lead a infinite loop. So check and fail early if tp->size if
greater or equal to msh.

Reported-by: Alexander Bulekov <alxndr@bu.edu>
Reported-by: Cheolwoo Myung <cwmyung@snu.ac.kr>
Reported-by: Ruhr-University Bochum <bugs-syssec@rub.de>
Cc: Prasad J Pandit <ppandit@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
 hw/net/e1000.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index d8da2f6..4345d86 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -670,6 +670,9 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp)
         msh = tp->tso_props.hdr_len + tp->tso_props.mss;
         do {
             bytes = split_size;
+            if (tp->size >= msh) {
+                goto eop;
+            }
             if (tp->size + bytes > msh)
                 bytes = msh - tp->size;
 
@@ -695,6 +698,7 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp)
         tp->size += split_size;
     }
 
+eop:
     if (!(txd_lower & E1000_TXD_CMD_EOP))
         return;
     if (!(tp->cptse && tp->size < tp->tso_props.hdr_len)) {
-- 
2.7.4