qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 12/15] ipmi: Add an SMBus IPMI interface


From: Peter Maydell
Subject: Re: [PATCH 12/15] ipmi: Add an SMBus IPMI interface
Date: Fri, 29 Jul 2022 16:34:44 +0100

On Tue, 28 Jun 2022 at 17:21, Peter Maydell <peter.maydell@linaro.org> 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>
> > ---
>
> 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):

Ping ?

> > +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.

thanks
-- PMM



reply via email to

[Prev in Thread] Current Thread [Next in Thread]