public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
From: David Gibson <david@gibson.dropbear.id.au>
To: passt-dev@passt.top, Stefano Brivio <sbrivio@redhat.com>
Cc: David Gibson <david@gibson.dropbear.id.au>
Subject: [PATCH 2/5] tap: Don't attempt to carry on if we get a bad frame length from qemu
Date: Fri, 26 Jul 2024 17:20:28 +1000	[thread overview]
Message-ID: <20240726072031.3941305-3-david@gibson.dropbear.id.au> (raw)
In-Reply-To: <20240726072031.3941305-1-david@gibson.dropbear.id.au>

If we receive a too-short or too-long frame from the QEMU socket, currently
we try to skip it and carry on.  That sounds sensible on first blush, but
probably isn't wise in practice.  If this happens, either (a) qemu has done
something seriously unexpected, or (b) we've received corrupt data over a
Unix socket.  Or more likely (c), we have a bug elswhere which has put us
out of sync with the stream, so we're trying to read something that's not a
frame length as a frame length.

Neither (b) nor (c) is really salvageable with the same stream.  Case (a)
might be ok, but we can no longer be confident qemu won't do something else
we can't cope with.

So, instead of just skipping the frame and trying to carry on, log an error
and close the socket.  As a bonus, establishing firm bounds on l2len early
will allow simplifications to how we deal with the case where a partial
frame is recv()ed.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 tap.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/tap.c b/tap.c
index a2ae7c2a..08700f65 100644
--- a/tap.c
+++ b/tap.c
@@ -1013,7 +1013,13 @@ redo:
 	}
 
 	while (n > (ssize_t)sizeof(uint32_t)) {
-		ssize_t l2len = ntohl(*(uint32_t *)p);
+		uint32_t l2len = ntohl(*(uint32_t *)p);
+
+		if (l2len < sizeof(struct ethhdr) || l2len > ETH_MAX_MTU) {
+			err("Invalid frame size from QEMU (corrupt stream?)");
+			tap_sock_reset(c);
+			return;
+		}
 
 		p += sizeof(uint32_t);
 		n -= sizeof(uint32_t);
@@ -1027,16 +1033,8 @@ redo:
 				return;
 		}
 
-		/* Complete the partial read above before discarding a malformed
-		 * frame, otherwise the stream will be inconsistent.
-		 */
-		if (l2len < (ssize_t)sizeof(struct ethhdr) ||
-		    l2len > (ssize_t)ETH_MAX_MTU)
-			goto next;
-
 		tap_add_packet(c, l2len, p);
 
-next:
 		p += l2len;
 		n -= l2len;
 	}
-- 
@@ -1013,7 +1013,13 @@ redo:
 	}
 
 	while (n > (ssize_t)sizeof(uint32_t)) {
-		ssize_t l2len = ntohl(*(uint32_t *)p);
+		uint32_t l2len = ntohl(*(uint32_t *)p);
+
+		if (l2len < sizeof(struct ethhdr) || l2len > ETH_MAX_MTU) {
+			err("Invalid frame size from QEMU (corrupt stream?)");
+			tap_sock_reset(c);
+			return;
+		}
 
 		p += sizeof(uint32_t);
 		n -= sizeof(uint32_t);
@@ -1027,16 +1033,8 @@ redo:
 				return;
 		}
 
-		/* Complete the partial read above before discarding a malformed
-		 * frame, otherwise the stream will be inconsistent.
-		 */
-		if (l2len < (ssize_t)sizeof(struct ethhdr) ||
-		    l2len > (ssize_t)ETH_MAX_MTU)
-			goto next;
-
 		tap_add_packet(c, l2len, p);
 
-next:
 		p += l2len;
 		n -= l2len;
 	}
-- 
2.45.2


  parent reply	other threads:[~2024-07-26  7:20 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-07-26  7:20 [PATCH 0/5] Fix assorted errors in the Qemu socket tap receive handler David Gibson
2024-07-26  7:20 ` [PATCH 1/5] tap: Better report errors receiving from QEMU socket David Gibson
2024-07-26 11:25   ` Stefano Brivio
2024-07-26 11:50     ` Stefano Brivio
2024-07-26 12:02     ` David Gibson
2024-07-26  7:20 ` David Gibson [this message]
2024-07-26 11:26   ` [PATCH 2/5] tap: Don't attempt to carry on if we get a bad frame length from qemu Stefano Brivio
2024-07-26  7:20 ` [PATCH 3/5] tap: Don't use EPOLLET on Qemu sockets David Gibson
2024-07-26  8:00   ` Stefano Brivio
2024-07-26 10:44     ` Stefano Brivio
2024-07-26 12:12     ` David Gibson
2024-07-26 13:25       ` Stefano Brivio
2024-07-29  1:15         ` David Gibson
2024-07-26  7:20 ` [PATCH 4/5] tap: Correctly handle frames of odd length David Gibson
2024-07-26  7:20 ` [PATCH 5/5] tap: Improve handling of partially received frames on qemu socket David Gibson
2024-07-26 11:39   ` Stefano Brivio
2024-07-26 12:33     ` David Gibson
2024-07-26 13:19 ` [PATCH 0/5] Fix assorted errors in the Qemu socket tap receive handler Stefano Brivio

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240726072031.3941305-3-david@gibson.dropbear.id.au \
    --to=david@gibson.dropbear.id.au \
    --cc=passt-dev@passt.top \
    --cc=sbrivio@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://passt.top/passt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).