From: David Gibson <david@gibson.dropbear.id.au>
To: Stefano Brivio <sbrivio@redhat.com>
Cc: passt-dev@passt.top, Matej Hrica <mhrica@redhat.com>
Subject: Re: [PATCH 4/4] tap: Drop frames from guest whose length is more than remaining buffer
Date: Fri, 28 Jun 2024 17:19:37 +1000 [thread overview]
Message-ID: <Zn5kCSAWxJoCzyWd@zatzit> (raw)
In-Reply-To: <20240627102057.2f452002@elisabeth>
[-- Attachment #1: Type: text/plain, Size: 3909 bytes --]
On Thu, Jun 27, 2024 at 10:21:04AM +0200, Stefano Brivio wrote:
> On Thu, 27 Jun 2024 11:30:02 +1000
> David Gibson <david@gibson.dropbear.id.au> wrote:
>
> > On Thu, Jun 27, 2024 at 01:45:36AM +0200, Stefano Brivio wrote:
> > > This was reported by Matej a while ago, but we forgot to fix it. Even
> > > if the hypervisor is necessarily trusted by passt, as it can in any
> > > case terminate the guest or disrupt guest connectivity, it's a good
> > > idea to be robust against possible issues.
> > >
> > > Instead of resetting the connection to the hypervisor, just skip the
> > > offending frame, as we had a few cases where QEMU would get the
> > > length descriptor wrong, in the past.
> > >
> > > Reported-by: Matej Hrica <mhrica@redhat.com>
> > > Suggested-by: Matej Hrica <mhrica@redhat.com>
> > > Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
> > > ---
> > > tap.c | 3 +++
> > > 1 file changed, 3 insertions(+)
> > >
> > > diff --git a/tap.c b/tap.c
> > > index 7f8c26d..bb993e0 100644
> > > --- a/tap.c
> > > +++ b/tap.c
> > > @@ -1026,6 +1026,9 @@ redo:
> >
> > So.. I just realised there's a different pre-existing problem here,
> > above what's quoted in the patch we have:
> >
> > ssize_t l2len = ntohl(*(uint32_t *)p);
> >
> > On a platform where ssize_t is only 32-bits we could get a negative
> > value here, which would be very bad.
>
> We can't, because the length is anyway limited to the maximum IPv4 path
> MTU in any hypervisor we might be talking to.
Only if we trust the hypervisor. And that the user didn't
misconfigure us to point the socket at something that's not actually a
hypervisor. And that it's not some future version of the hypervisor
configured to use a different framing format. And that our code is
robust enough to never get out of sync on the stream.
I really think it's better to read this into a u32, and range sanity
check it before we do anything else.
> > So l2len should be a uint32_t, not ssize_t.
>
> True, I can also change that while at it.
>
> > We do then need to make sure that the comparison between
> > l2len and n is unsigned - it's safe to cast n to size_t there, because
> > we've verified it's positive as the loop condition.
> >
> > Or... maybe it's simpler. The frame length is encoded as 32-bits, but
> > we can't meaningfully have frames above 64k (maybe 64k+ETH_HLEN). So
> > possibly we should just reset the tap connection if we see such a
> > frame (most likely it means we've somehow gotten out of sync, anyway).
>
> I'd rather "fix" type and comparison, for the sake of whatever static
> checkers might eventually come up with.
>
> > > p += sizeof(uint32_t);
> > > n -= sizeof(uint32_t);
> >
> >
> > > + if (l2len > (ssize_t)TAP_BUF_BYTES - n)
> >
> > I hate to discard valid frames from the guest.
>
> That won't happen because of how TAP_BUF_FILL and TAP_BUF_BYTES are
> defined. If this condition is true, the length descriptor actually
> mismatched. If you have a better proposal, let me know.
Hmm.. I'll have a look.
> > > + goto next;
> >
> > ..and this is not safe. This skips (l2len > n) check, which means
> > that the n -= l2len at next could now have a signed overflow, which is
> > UB.
>
> It's safe because of the change from 3/4, which will just return on
> overflow. In any case, yes, I can add a return directly, it's not very
> productive to speculate what kind of issues a hypervisor might have,
> let's just avoid crashing in case.
>
> > > +
> > > /* At most one packet might not fit in a single read, and this
> > > * needs to be blocking.
> > > */
> >
>
--
David Gibson (he or they) | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you, not the other way
| around.
http://www.ozlabs.org/~dgibson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
next prev parent reply other threads:[~2024-06-28 7:19 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-26 23:45 [PATCH 0/4] Small, assorted "hardening" fixes Stefano Brivio
2024-06-26 23:45 ` [PATCH 1/4] conf: Copy up to MAXDNSRCH - 1 bytes, not MAXDNSRCH Stefano Brivio
2024-06-27 0:45 ` David Gibson
2024-06-27 7:27 ` Stefano Brivio
2024-06-27 10:11 ` David Gibson
2024-06-26 23:45 ` [PATCH 2/4] tcp_splice: Check return value of setsockopt() for SO_RCVLOWAT Stefano Brivio
2024-06-27 0:46 ` David Gibson
2024-06-26 23:45 ` [PATCH 3/4] util, lineread, tap: Overflow checks on long signed sums and subtractions Stefano Brivio
2024-06-27 1:13 ` David Gibson
2024-06-27 7:55 ` Stefano Brivio
2024-06-27 20:46 ` Stefano Brivio
2024-06-28 7:15 ` David Gibson
2024-06-28 7:11 ` David Gibson
2024-06-28 7:55 ` Stefano Brivio
2024-06-28 18:30 ` Stefano Brivio
2024-07-08 13:01 ` Stefano Brivio
2024-06-26 23:45 ` [PATCH 4/4] tap: Drop frames from guest whose length is more than remaining buffer Stefano Brivio
2024-06-27 1:30 ` David Gibson
2024-06-27 8:21 ` Stefano Brivio
2024-06-28 7:19 ` David Gibson [this message]
2024-06-28 7:56 ` 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=Zn5kCSAWxJoCzyWd@zatzit \
--to=david@gibson.dropbear.id.au \
--cc=mhrica@redhat.com \
--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).