All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Maydell <peter.maydell@linaro.org>
To: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Michael Roth <mdroth@linux.vnet.ibm.com>,
	qemu-stable <qemu-stable@nongnu.org>,
	"Dr. David Alan Gilbert" <dgilbert@redhat.com>,
	QEMU Developers <qemu-devel@nongnu.org>
Subject: Re: [Qemu-devel] [PATCH v4 13/30] stellaris_enet: avoid buffer overrun on incoming migration
Date: Mon, 31 Mar 2014 22:13:04 +0100	[thread overview]
Message-ID: <CAFEAcA_O88N17gPYS+ABWZJJRJFmrnti83ofJpc+bu3sCEbNMA@mail.gmail.com> (raw)
In-Reply-To: <20140331204900.GC12403@redhat.com>

On 31 March 2014 21:49, Michael S. Tsirkin <mst@redhat.com> wrote:
> On Mon, Mar 31, 2014 at 06:11:22PM +0100, Dr. David Alan Gilbert wrote:
>> * Michael S. Tsirkin (mst@redhat.com) wrote:
>> > CVE-2013-4532
>> >
>> > s->next_packet is read from wire as an index into s->rx[]. If
>> > s->next_packet exceeds the length of s->rx[], the buffer can be
>> > subsequently overrun with arbitrary data from the wire.
>> >
>> > Fix this by failing migration if s->next_packet we read from
>> > the wire exceeds this.
>> >
>> > Similarly, validate rx_fifo against sizeof(s->rx[].data).
>> >
>> > Finally, constrain rx len to a sensibly small positive
>> > value, to avoid integer overruns when data model
>> > later uses this value.
>> >
>> > Reported-by: Michael Roth <mdroth@linux.vnet.ibm.com>
>> > Reported-by: Peter Maydell <peter.maydell@linaro.org>
>> > Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
>> > ---
>> >  hw/net/stellaris_enet.c | 24 ++++++++++++++++++++----
>> >  1 file changed, 20 insertions(+), 4 deletions(-)
>> >
>> > diff --git a/hw/net/stellaris_enet.c b/hw/net/stellaris_enet.c
>> > index d04e6a4..182fd3e 100644
>> > --- a/hw/net/stellaris_enet.c
>> > +++ b/hw/net/stellaris_enet.c
>> > @@ -358,7 +358,7 @@ static void stellaris_enet_save(QEMUFile *f, void *opaque)
>> >  static int stellaris_enet_load(QEMUFile *f, void *opaque, int version_id)
>> >  {
>> >      stellaris_enet_state *s = (stellaris_enet_state *)opaque;
>> > -    int i;
>> > +    int i, v;
>> >
>> >      if (version_id != 1)
>> >          return -EINVAL;
>> > @@ -381,9 +381,25 @@ static int stellaris_enet_load(QEMUFile *f, void *opaque, int version_id)
>> >          qemu_get_buffer(f, s->rx[i].data, sizeof(s->rx[i].data));
>> >
>> >      }
>>
>> The loop that's just off the top here is:
>>     for (i = 0; i < 31; i++) {
>>         s->rx[i].len = qemu_get_be32(f);
>>         qemu_get_buffer(f, s->rx[i].data, sizeof(s->rx[i].data));
>>
>>     }
>>
>> Doesn't that 'len' need validating? I assume it's the size of the
>> packet in the fixed sized buffer? (??)
>
> Not that I see where it's used as such.

In the DATA case of stellaris_enet_read() -- when the current
rx_fifo_len goes to zero we will uncritically set rx_fifo_len to
s->rx[s->next_packet].len. So we must validate that it's between
0 and 2048 (the size of the rx[].data array), otherwise further
reads from DATA will be able to run off the end of the data array
for the following packet.

>> > -    s->next_packet = qemu_get_be32(f);
>> > -    s->rx_fifo = s->rx[s->next_packet].data + qemu_get_be32(f);
>> > -    s->rx_fifo_len = qemu_get_be32(f);
>> > +    v = qemu_get_be32(f);
>> > +    if (v < 0 || v >= ARRAY_SIZE(s->rx)) {
>> > +        return -EINVAL;
>> > +    }
>> > +    s->next_packet = v;
>> > +    v = qemu_get_be32(f);
>> > +    if (v < 0 || v >= sizeof(s->rx[i].data)) {
>> > +        return -EINVAL;
>> > +    }
>> > +    s->rx_fifo = s->rx[s->next_packet].data + v;
>> > +    v = qemu_get_be32(f);
>> > +    /* Set limit low enough to avoid integer overflow when
>> > +     * we do math on len later, but high enough to avoid
>> > +     * truncating any packets.
>> > +     */
>> > +    if (v < 0 || v >= 0x100000) {
>> > +        return -EINVAL;
>> > +    }
>> > +    s->rx_fifo_len = v;
>>
>> I don't understand this - isn't the requirement that rx_fifo+rx_fifo_len be within
>> the buffer (or I think it might be legal for the sum to point to the byte after the
>> buffer)?
>> My (quick first ever look at this code) reading is that rx_fifo and rx_fifo_len
>> related to the current packet in-flight; although I've not quite convinced myself
>> about what is supposed to happen at the end of the packet (which is why
>> I say rx_fifo might point just at? the end.

> Actually I forgot why I wrote this last check.
> Peter said we should and I thought I see the issue ...
> But I no longer see what kind of damage can rx_fifo_len cause
> unless validated.

Again, look at the DATA read logic. Every time the guest does a
DATA read, we read from the four bytes at s->rx_fifo, increment
rx_fifo by 4 and decrement rx_fifo_len by 4. When rx_fifo_len
eventually goes to zero we will (on the subsequent read) reset
both rx_fifo and rx_fifo_len from the next packet in the rx queue.
So if the incoming data sets rx_fifo_len to (let us say) 0x10000,
then the guest can cause us to read well off the end of the rx data
array. This means your check isn't tight enough -- we need to
ensure that rx_fifo and rx_fifo_len between them define a window
into the rx data and nowhere else. As David says this means you
need:

    v1 = qemu_get_be32(f);
    if (v1 < 0 || v1 > sizeof(s->rx[i].data)) {
        return -EINVAL;
    }
    s->rx_fifo = s->rx[s->next_packet].data + v1;
    v2 = qemu_get_be32(f);
    if (v2 < 0 || v1 + v2 > sizeof(s->rx[i].data)) {
        return -EINVAL;
    }
    s->rx_fifo_len = v2;

The max check on v1 is actually only there to ensure that we
don't have to think about integer overflow when we do the
upper-bound check on v1 + v2. Note that v1 == sizeof(array)
is OK if (and only if) v2 == 0.

An assert in stellaris_enet_receive() that the net code never
hands us a packet we can't fit in the array wouldn't go amiss
either, but that's a separate issue.

thanks
-- PMM

  reply	other threads:[~2014-03-31 21:14 UTC|newest]

Thread overview: 81+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-03-31 14:15 [Qemu-devel] [PATCH v4 00/30] qemu state loading issues Michael S. Tsirkin
2014-03-31 14:15 ` [Qemu-devel] [PATCH v4 01/30] vmstate: reduce code duplication Michael S. Tsirkin
2014-03-31 15:01   ` Dr. David Alan Gilbert
2014-03-31 15:27     ` Michael S. Tsirkin
2014-03-31 14:16 ` [Qemu-devel] [PATCH v4 02/30] vmstate: add VMS_MUST_EXIST Michael S. Tsirkin
2014-03-31 14:16 ` [Qemu-devel] [PATCH v4 03/30] vmstate: add VMSTATE_VALIDATE Michael S. Tsirkin
2014-04-01 10:39   ` Dr. David Alan Gilbert
2014-03-31 14:16 ` [Qemu-devel] [PATCH v4 04/30] virtio-net: fix buffer overflow on invalid state load Michael S. Tsirkin
2014-03-31 17:21   ` Laszlo Ersek
2014-03-31 19:34     ` Michael S. Tsirkin
2014-03-31 14:16 ` [Qemu-devel] [PATCH v4 05/30] virtio-net: out-of-bounds buffer write on load Michael S. Tsirkin
2014-04-01  8:45   ` Dr. David Alan Gilbert
2014-03-31 14:16 ` [Qemu-devel] [PATCH v4 06/30] virtio-net: out-of-bounds buffer write on invalid state load Michael S. Tsirkin
2014-03-31 14:16 ` [Qemu-devel] [PATCH v4 07/30] virtio: " Michael S. Tsirkin
2014-03-31 14:16 ` [Qemu-devel] [PATCH v4 08/30] ahci: fix buffer overrun " Michael S. Tsirkin
2014-03-31 15:31   ` Peter Maydell
2014-03-31 14:16 ` [Qemu-devel] [PATCH v4 09/30] hpet: " Michael S. Tsirkin
2014-03-31 14:16 ` [Qemu-devel] [PATCH v4 10/30] hw/pci/pcie_aer.c: fix buffer overruns " Michael S. Tsirkin
2014-04-01 10:56   ` Dr. David Alan Gilbert
2014-03-31 14:16 ` [Qemu-devel] [PATCH v4 11/30] pl022: fix buffer overun " Michael S. Tsirkin
2014-03-31 15:04   ` Peter Maydell
2014-03-31 14:16 ` [Qemu-devel] [PATCH v4 12/30] vmstate: fix buffer overflow in target-arm/machine.c Michael S. Tsirkin
2014-03-31 15:40   ` Peter Maydell
2014-04-01 15:12     ` Michael S. Tsirkin
2014-03-31 14:16 ` [Qemu-devel] [PATCH v4 13/30] stellaris_enet: avoid buffer overrun on incoming migration Michael S. Tsirkin
2014-03-31 17:11   ` Dr. David Alan Gilbert
2014-03-31 20:49     ` Michael S. Tsirkin
2014-03-31 21:13       ` Peter Maydell [this message]
2014-04-01 15:19         ` Michael S. Tsirkin
2014-03-31 14:16 ` [Qemu-devel] [PATCH v4 14/30] stellaris_enet: avoid buffer overrun on incoming migration (part 2) Michael S. Tsirkin
2014-04-01  9:43   ` Dr. David Alan Gilbert
2014-04-01 10:05     ` Peter Maydell
2014-04-01 11:52       ` Peter Maydell
2014-03-31 14:16 ` [Qemu-devel] [PATCH v4 15/30] stellaris_enet: avoid buffer orerrun on incoming migration (part 3) Michael S. Tsirkin
2014-04-01  9:51   ` Dr. David Alan Gilbert
2014-04-01 10:06     ` Peter Maydell
2014-04-01 15:22       ` Michael S. Tsirkin
2014-04-01 15:56         ` Peter Maydell
2014-04-01 14:42   ` Eric Blake
2014-03-31 14:16 ` [Qemu-devel] [PATCH v4 16/30] virtio: avoid buffer overrun on incoming migration Michael S. Tsirkin
2014-03-31 16:09   ` Peter Maydell
2014-03-31 14:17 ` [Qemu-devel] [PATCH v4 17/30] openpic: " Michael S. Tsirkin
2014-03-31 15:55   ` Peter Maydell
2014-03-31 14:17 ` [Qemu-devel] [PATCH v4 18/30] virtio: validate num_sg when mapping Michael S. Tsirkin
2014-04-01  9:10   ` Amit Shah
2014-03-31 14:17 ` [Qemu-devel] [PATCH v4 19/30] pxa2xx: avoid buffer overrun on incoming migration Michael S. Tsirkin
2014-03-31 15:29   ` Peter Maydell
2014-03-31 17:26   ` Don Koch
2014-03-31 14:17 ` [Qemu-devel] [PATCH v4 20/30] ssi-sd: fix buffer overrun on invalid state load Michael S. Tsirkin
2014-03-31 15:44   ` Peter Maydell
2014-03-31 14:17 ` [Qemu-devel] [PATCH v4 21/30] ssd0323: fix buffer overun " Michael S. Tsirkin
2014-03-31 15:35   ` Peter Maydell
2014-03-31 14:17 ` [Qemu-devel] [PATCH v4 22/30] tsc210x: fix buffer overrun " Michael S. Tsirkin
2014-03-31 15:39   ` Peter Maydell
2014-03-31 14:17 ` [Qemu-devel] [PATCH v4 23/30] zaurus: " Michael S. Tsirkin
2014-04-01 11:18   ` Dr. David Alan Gilbert
2014-03-31 14:17 ` [Qemu-devel] [PATCH v4 24/30] usb: sanity check setup_index+setup_len in post_load Michael S. Tsirkin
2014-03-31 15:48   ` Peter Maydell
2014-04-01  6:23     ` Gerd Hoffmann
2014-03-31 14:17 ` [Qemu-devel] [PATCH v4 25/30] virtio-scsi: fix buffer overrun on invalid state load Michael S. Tsirkin
2014-03-31 14:17 ` [Qemu-devel] [PATCH v4 26/30] savevm: fix potential segfault on invalid state Michael S. Tsirkin
2014-03-31 16:04   ` Peter Maydell
2014-03-31 14:17 ` [Qemu-devel] [PATCH v4 27/30] vmxnet3: validate interrupt indices coming from guest Michael S. Tsirkin
2014-03-31 15:45   ` Dr. David Alan Gilbert
2014-04-01  9:54     ` Dmitry Fleytman
2014-04-01 10:03       ` Dr. David Alan Gilbert
2014-04-01 11:33   ` Dr. David Alan Gilbert
2014-04-01 13:04     ` Dmitry Fleytman
2014-04-01 13:07       ` Dr. David Alan Gilbert
2014-04-03 16:07         ` Michael S. Tsirkin
2014-04-04  9:47           ` Dmitry Fleytman
2014-03-31 14:17 ` [Qemu-devel] [PATCH v4 28/30] vmxnet3: validate interrupt indices read on migration Michael S. Tsirkin
2014-03-31 16:33   ` Dr. David Alan Gilbert
2014-03-31 19:38     ` Michael S. Tsirkin
2014-04-01 10:15       ` Dmitry Fleytman
2014-03-31 14:17 ` [Qemu-devel] [PATCH v4 29/30] vmxnet3: validate queues configuration coming from quest Michael S. Tsirkin
2014-03-31 15:48   ` Dr. David Alan Gilbert
2014-04-01 10:04     ` Dmitry Fleytman
2014-04-01 14:52       ` Michael S. Tsirkin
2014-04-01 18:40         ` Dmitry Fleytman
2014-03-31 14:17 ` [Qemu-devel] [PATCH v4 30/30] vmxnet3: validate queues configuration read on migration Michael S. Tsirkin

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=CAFEAcA_O88N17gPYS+ABWZJJRJFmrnti83ofJpc+bu3sCEbNMA@mail.gmail.com \
    --to=peter.maydell@linaro.org \
    --cc=dgilbert@redhat.com \
    --cc=mdroth@linux.vnet.ibm.com \
    --cc=mst@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-stable@nongnu.org \
    /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.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.