Re: 4.6-rc2 regression with commit 104daa71b396: check VPD access offset against length

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

 



| From: linux-pci-owner@xxxxxxxxxxxxxxx <linux-pci-owner@xxxxxxxxxxxxxxx> on behalf of Hannes Reinecke <hare@xxxxxxxx>
| Sent: Tuesday, April 12, 2016 11:00 PM
|
| On 04/12/2016 07:35 PM, Casey Leedom wrote:
| > | From: Hannes Reinecke <hare@xxxxxxxx>
| > | Sent: Tuesday, April 12, 2016 1:46 AM
| > | ...
| > | > --- a/drivers/pci/access.c
| > | > +++ a/drivers/pci/access.c
| > | > ...
| > | > @@ -392,13 +405,8 @@ static ssize_t pci_vpd_read(struct pci_dev *dev, loff_t pos, size_t count,
| > | >       if (vpd->len == 0)
| > | >               return -EIO;
| > | >
| > | > -     if (pos > vpd->len)
| > | > -             return 0;
| > | > -
| > | > -     if (end > vpd->len) {
| > | > -             end = vpd->len;
| > | > -             count = end - pos;
| > | > -     }
| > | > +     if (end > vpd->len)
| > | > +             return -EINVAL;
| > | >
| > | >       if (mutex_lock_killable(&vpd->lock))
| > | >               return -EINTR;
| > |
| > | Why do you need this change?
| > | We still would be needing to validate 'pos', don't we?
| > | I'd prefer not to have this bit in.
| >
| > Two reasons:
| >
| >  1. It makes pci_vpd_read() with pci_vpd_write() which has exactly this
| >     logic.
| >
| >  2. More importantly, the new implementation of pci_read_vpd() silently
| >     fails to perform a VPD read and allows the caller to use random stack
| >     garbage in the read buffer without knowing that it's not really VPD
| >     contents.  If any portion of the VPD read isn't going to be performed,
| >     we should signal that back to the caller.  We could either return an
| >     error or we could return the number of bytes actually read.  The problem
| >     with the latter is that it would require changing every single caller to
| >     check for Requested Read Length == Actual Read Length.  Returning an
| >     error is the more conservative fix and allows for rapid diagnosis of
| >     problems.
| >
| >     And that last point is important because I spent quite a bit of time
| >     digging around trying to figure out why cxgb4 suddenly wasn't working.
|
| Okay. But wouldn't we need to check for 'pos' exceeding 'vpd->len', too?

Nope.  "pos", "count", and "end" are unsigned:

    loff_t end = pos + count;

If "pos" is greater than "vpd->len", "end" will be as well.  This is actually
exactly the same code that's already in pci_vpd_write().

Casey
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux