All of lore.kernel.org
 help / color / mirror / Atom feed
From: Corey Minyard <minyard@acm.org>
To: Peter Maydell <peter.maydell@linaro.org>
Cc: "QEMU Developers" <qemu-devel@nongnu.org>,
	"Michael S . Tsirkin" <mst@redhat.com>,
	"Igor Mammedov" <imammedo@redhat.com>,
	"M : Marcel Apfelbaum" <marcel.apfelbaum@gmail.com>,
	"David Gibson" <david@gibson.dropbear.id.au>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Marc-André Lureau" <marcandre.lureau@redhat.com>
Subject: Re: [PATCH 12/15] ipmi: Add an SMBus IPMI interface
Date: Fri, 29 Jul 2022 10:56:44 -0500	[thread overview]
Message-ID: <20220729155644.GY3834@minyard.net> (raw)
In-Reply-To: <CAFEAcA88GqrqoENf8NHxeNgTjj-jutz8Kspk43L1gp_VJJdh+Q@mail.gmail.com>

On Tue, Jun 28, 2022 at 05:21:44PM +0100, Peter Maydell wrote:
> On Thu, 19 Sept 2019 at 22:39, <minyard@acm.org> wrote:
> >
> > From: Corey Minyard <cminyard@mvista.com>
> >
> > Signed-off-by: Corey Minyard <cminyard@mvista.com>
> > ---
> 

Thank you for the ping.  Comments inline...

> Very old patch, but Coverity has decided it doesn't like something
> in this function that's still basically the same in the current codebase
> (CID 1487146):
> 
> > +static int ipmi_write_data(SMBusDevice *dev, uint8_t *buf, uint8_t len)
> > +{
> > +    SMBusIPMIDevice *sid = SMBUS_IPMI(dev);
> > +    bool send = false;
> > +    uint8_t cmd;
> > +    int ret = 0;
> > +
> > +    /* length is guaranteed to be >= 1. */
> > +    cmd = *buf++;
> > +    len--;
> > +
> > +    /* Handle read request, which don't have any data in the write part. */
> > +    switch (cmd) {
> > +    case SSIF_IPMI_RESPONSE:
> > +        sid->currblk = 0;
> > +        ret = ipmi_load_readbuf(sid);
> > +        break;
> > +
> > +    case SSIF_IPMI_MULTI_PART_RESPONSE_MIDDLE:
> > +        sid->currblk++;
> > +        ret = ipmi_load_readbuf(sid);
> > +        break;
> > +
> > +    case SSIF_IPMI_MULTI_PART_RETRY:
> > +        if (len >= 1) {
> > +            sid->currblk = buf[0];
> > +            ret = ipmi_load_readbuf(sid);
> > +        } else {
> > +            ret = -1;
> > +        }
> > +        break;
> > +
> > +    default:
> > +        break;
> > +    }
> > +
> > +    /* This should be a message write, make the length is there and correct. */
> > +    if (len >= 1) {
> > +        if (*buf != len - 1 || *buf > MAX_SSIF_IPMI_MSG_CHUNK) {
> > +            return -1; /* Bogus message */
> > +        }
> > +        buf++;
> > +        len--;
> > +    }
> 
> After all of this preamble, len can be zero...
> 
> > +
> > +    switch (cmd) {
> > +    case SSIF_IPMI_REQUEST:
> > +        send = true;
> > +        /* FALLTHRU */
> > +    case SSIF_IPMI_MULTI_PART_REQUEST_START:
> > +        if (len < 2) {
> > +            return -1; /* Bogus. */
> > +        }
> > +        memcpy(sid->inmsg, buf, len);
> > +        sid->inlen = len;
> > +        break;
> > +
> > +    case SSIF_IPMI_MULTI_PART_REQUEST_END:
> > +        send = true;
> > +        /* FALLTHRU */
> > +    case SSIF_IPMI_MULTI_PART_REQUEST_MIDDLE:
> > +        if (!sid->inlen) {
> > +            return -1; /* Bogus. */
> > +        }
> > +        if (sid->inlen + len > MAX_SSIF_IPMI_MSG_SIZE) {
> > +            sid->inlen = 0; /* Discard the message. */
> > +            return -1; /* Bogus. */
> > +        }
> 
> ...this error checking on the values of the 'middle' request
> means that after one 'middle' request we can end up with
> sid->inlen == MAX_SSIF_IPMI_MSG_SIZE (ie we filled the
> entire sid->inmsg[] array).
> 
> But then if we get another 'middle' request with len == 0,
> that will pass this error checking because (sid->inlen + len == MSG_SIZE)
> and fall through into...
> 
> > +        if (len < 32) {
> > +            /*
> > +             * Special hack, a multi-part middle that is less than 32 bytes
> > +             * marks the end of a message.  The specification is fairly
> > +             * confusing, so some systems to this, even sending a zero
> > +             * length end message to mark the end.
> > +             */
> > +            send = true;
> > +        }
> > +        memcpy(sid->inmsg + sid->inlen, buf, len);
> 
> ...calling memcpy() with argument 1 being a pointer that points
> one past the end of the array. Even though len will be 0 and
> we won't memcpy() anything, this is (depending on how you choose
> to intepret things the C standard doesn't come right out and state
> explicitly) undefined behaviour, because memcpy() wants to be passed
> valid pointers, even if you ask it to do no work with a zero len.
> 
> This isn't going to be a visible bug in practical terms, but it would
> make Coverity happy if we either (a) rejected a request with an empty
> length or else (b) skipped the memcpy(). I don't know enough about
> IPMI to know which is better.

Hmm.  In some cases you have to accept a zero-length packet (as
described in the comments), but if you said:

  if (len > 0)
      memcpy(sid->inmsg + sid->inlen, buf, len);

would that make Coverity happy?  I was under the impression that if you
passed zero into len, you could pass anything into the data on a memcpy.
But apparently not; I can make this change.

-corey

> 
> > +        sid->inlen += len;
> > +        break;
> > +    }
> > +
> > +    if (send && sid->inlen) {
> > +        smbus_ipmi_send_msg(sid);
> > +    }
> > +
> > +    return ret;
> > +}
> 
> thanks
> -- PMM
> 


  parent reply	other threads:[~2022-07-29 15:57 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-19 21:39 [PATCH 00/15] ipmi: Bug fixes, add new interfaces minyard
2019-09-19 21:39 ` [PATCH 01/15] ipmi: Fix watchdog NMI handling minyard
2019-09-20 15:45   ` Cédric Le Goater
2019-09-19 21:39 ` [PATCH 02/15] ipmi: Fix the get watchdog command minyard
2019-09-20 15:50   ` Cédric Le Goater
2019-09-19 21:39 ` [PATCH 03/15] ipmi: Generate an interrupt on watchdog pretimeout expiry minyard
2019-09-23  5:41   ` Cédric Le Goater
2019-09-19 21:39 ` [PATCH 04/15] tests:ipmi: Fix IPMI BT tests minyard
2019-09-19 21:39 ` [PATCH 05/15] qdev: Add a no default uuid property minyard
2019-09-23  5:47   ` Cédric Le Goater
2019-09-19 21:39 ` [PATCH 06/15] ipmi: Add a UUID device property minyard
2019-09-23  5:51   ` Cédric Le Goater
2019-09-19 21:39 ` [PATCH 07/15] ipmi: Split out KCS-specific code from ISA KCS code minyard
2019-09-19 21:39 ` [PATCH 08/15] ipmi: Split out BT-specific code from ISA BT code minyard
2019-09-19 21:39 ` [PATCH 09/15] ipmi: Allow a size value to be passed for I/O space minyard
2019-09-19 21:39 ` [PATCH 10/15] smbios:ipmi: Ignore IPMI devices with no fwinfo function minyard
2019-09-19 21:39 ` [PATCH 11/15] ipmi: Add PCI IPMI interfaces minyard
2019-09-19 21:39 ` [PATCH 12/15] ipmi: Add an SMBus IPMI interface minyard
2022-06-28 16:21   ` Peter Maydell
2022-07-29 15:34     ` Peter Maydell
2022-07-29 15:56     ` Corey Minyard [this message]
2022-07-29 16:01       ` Peter Maydell
2019-09-19 21:39 ` [PATCH 13/15] acpi: Add i2c serial bus CRS handling minyard
2019-09-19 21:39 ` [PATCH 14/15] ipmi: Fix SSIF ACPI handling to use the right CRS minyard
2019-09-19 21:39 ` [PATCH 15/15] pc: Add an SMB0 ACPI device to q35 minyard
2019-09-20 11:43 ` [PATCH 00/15] ipmi: Bug fixes, add new interfaces Paolo Bonzini
2019-09-20 12:19   ` Corey Minyard
2019-09-20 12:57 ` Peter Maydell
2019-09-20 17:36   ` Corey Minyard
2019-09-20 17:51     ` Peter Maydell

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=20220729155644.GY3834@minyard.net \
    --to=minyard@acm.org \
    --cc=david@gibson.dropbear.id.au \
    --cc=imammedo@redhat.com \
    --cc=marcandre.lureau@redhat.com \
    --cc=marcel.apfelbaum@gmail.com \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@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.