* [PATCH 0/2] pci: config space bounds check and correction
@ 2011-07-20 23:46 Donald Dutile
2011-07-20 23:49 ` [PATCH 1/2] pci: bounds check offsets into config_map Donald Dutile
2011-07-20 23:51 ` [PATCH 2/2] pci: correct pci config size default for cap version 2 endpoints Donald Dutile
0 siblings, 2 replies; 7+ messages in thread
From: Donald Dutile @ 2011-07-20 23:46 UTC (permalink / raw)
To: kvm; +Cc: alex.williamson, mst
Doing device assignement using a PCIe device with it's
PCI Cap structure at offset 0xcc showed a problem in
the default size mapped for this cap-id.
The failure caused a corruption which might have gone unnoticed
otherwise.
So, add a bounds check in pci_add_capability() & fprintf()
to detail which device & cap structure. While there, adjust
overlap check to prefix output with '0x' so it's clear in output.
Note: bounds check a bit odd looking, but that's because offset & size
are uint8's and comparing to greater than 256.
Next, fix assigned_device_pci_cap_init() to set the default
size of PCIe Cap structure (cap-id 0x10) to 0x34 instead of 0x3c.
0x34 is default, min, for endpoint device with a cap version of 2.
Algorithm will have to get a bit more complicated if
non-endpoint (mriov-based switches?) are ever device-assigned.
Signed-off-by: Donald Dutile <ddutile@redhat.com>
cc: Alex Williamson <alex.williamson@redhat.com>
cc: Michael S. Tsirkin <mst@redhat.com>
---
Donald Dutile (2):
pci: correct pci config size default for cap version 2 endpoints
pci: bounds check offsets into config_map
hw/device-assignment.c | 4 +++-
hw/pci.c | 16 ++++++++++++++--
2 files changed, 17 insertions(+), 3 deletions(-)
--
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH 1/2] pci: bounds check offsets into config_map 2011-07-20 23:46 [PATCH 0/2] pci: config space bounds check and correction Donald Dutile @ 2011-07-20 23:49 ` Donald Dutile 2011-07-21 8:11 ` Michael S. Tsirkin 2011-07-20 23:51 ` [PATCH 2/2] pci: correct pci config size default for cap version 2 endpoints Donald Dutile 1 sibling, 1 reply; 7+ messages in thread From: Donald Dutile @ 2011-07-20 23:49 UTC (permalink / raw) To: kvm; +Cc: alex.williamson, mst Bounds check to avoid walking off config_map[] and corrupting what is after it. Signed-off-by: Donald Dutile <ddutile@redhat.com> cc: Alex Williamson <alex.williamson@redhat.com> cc: Michael S. Tsirkin <mst@redhat.com> --- hw/pci.c | 16 ++++++++++++++-- 1 files changed, 14 insertions(+), 2 deletions(-) diff --git a/hw/pci.c b/hw/pci.c index 5deaa04..9a7ff2d 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -2078,12 +2078,24 @@ int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, } } else { int i; + uint32_t config_size = pci_config_size(pdev); + + /* ensure don't walk off end of config_map[] */ + if (offset > (config_size - size)) { + fprintf(stderr, "ERROR: %04x:%02x:%02x.%x " + "Attempt to add PCI capability 0x%x at offset 0x%x," + "size 0x%x, which exceeds emulated PCI config space 0x%x\n", + pci_find_domain(pdev->bus), pci_bus_num(pdev->bus), + PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), + cap_id, offset, size, config_size); + return -EINVAL; + } for (i = offset; i < offset + size; i++) { if (pdev->config_map[i]) { fprintf(stderr, "ERROR: %04x:%02x:%02x.%x " - "Attempt to add PCI capability %x at offset " - "%x overlaps existing capability %x at offset %x\n", + "Attempt to add PCI capability 0x%x at offset " + "0x%x overlaps existing capability 0x%x at offset 0x%x\n", pci_find_domain(pdev->bus), pci_bus_num(pdev->bus), PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), cap_id, offset, pdev->config_map[i], i); ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] pci: bounds check offsets into config_map 2011-07-20 23:49 ` [PATCH 1/2] pci: bounds check offsets into config_map Donald Dutile @ 2011-07-21 8:11 ` Michael S. Tsirkin 2011-07-21 15:52 ` Don Dutile 0 siblings, 1 reply; 7+ messages in thread From: Michael S. Tsirkin @ 2011-07-21 8:11 UTC (permalink / raw) To: Donald Dutile; +Cc: kvm, alex.williamson On Wed, Jul 20, 2011 at 07:49:34PM -0400, Donald Dutile wrote: > Bounds check to avoid walking off config_map[] > and corrupting what is after it. > > Signed-off-by: Donald Dutile <ddutile@redhat.com> > cc: Alex Williamson <alex.williamson@redhat.com> > cc: Michael S. Tsirkin <mst@redhat.com> > --- > > hw/pci.c | 16 ++++++++++++++-- > 1 files changed, 14 insertions(+), 2 deletions(-) > > diff --git a/hw/pci.c b/hw/pci.c > index 5deaa04..9a7ff2d 100644 > --- a/hw/pci.c > +++ b/hw/pci.c > @@ -2078,12 +2078,24 @@ int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, > } > } else { > int i; > + uint32_t config_size = pci_config_size(pdev); This is actually slightly wrong: even for express devices, legacy capabilities can not spill out from the low 256 bytes: the extended config space has its own capability list always starting with the express capability at offset 256. > + > + /* ensure don't walk off end of config_map[] */ > + if (offset > (config_size - size)) { I prefer not to have () around math here. > + fprintf(stderr, "ERROR: %04x:%02x:%02x.%x " > + "Attempt to add PCI capability 0x%x at offset 0x%x," > + "size 0x%x, which exceeds emulated PCI config space 0x%x\n", > + pci_find_domain(pdev->bus), pci_bus_num(pdev->bus), > + PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), > + cap_id, offset, size, config_size); > + return -EINVAL; > + } > > for (i = offset; i < offset + size; i++) { > if (pdev->config_map[i]) { > fprintf(stderr, "ERROR: %04x:%02x:%02x.%x " > - "Attempt to add PCI capability %x at offset " > - "%x overlaps existing capability %x at offset %x\n", > + "Attempt to add PCI capability 0x%x at offset " > + "0x%x overlaps existing capability 0x%x at offset 0x%x\n", > pci_find_domain(pdev->bus), pci_bus_num(pdev->bus), > PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), > cap_id, offset, pdev->config_map[i], i); ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] pci: bounds check offsets into config_map 2011-07-21 8:11 ` Michael S. Tsirkin @ 2011-07-21 15:52 ` Don Dutile 0 siblings, 0 replies; 7+ messages in thread From: Don Dutile @ 2011-07-21 15:52 UTC (permalink / raw) To: Michael S. Tsirkin; +Cc: kvm, alex.williamson On 07/21/2011 04:11 AM, Michael S. Tsirkin wrote: > On Wed, Jul 20, 2011 at 07:49:34PM -0400, Donald Dutile wrote: >> Bounds check to avoid walking off config_map[] >> and corrupting what is after it. >> >> Signed-off-by: Donald Dutile<ddutile@redhat.com> >> cc: Alex Williamson<alex.williamson@redhat.com> >> cc: Michael S. Tsirkin<mst@redhat.com> >> --- >> >> hw/pci.c | 16 ++++++++++++++-- >> 1 files changed, 14 insertions(+), 2 deletions(-) >> >> diff --git a/hw/pci.c b/hw/pci.c >> index 5deaa04..9a7ff2d 100644 >> --- a/hw/pci.c >> +++ b/hw/pci.c >> @@ -2078,12 +2078,24 @@ int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, >> } >> } else { >> int i; >> + uint32_t config_size = pci_config_size(pdev); > > This is actually slightly wrong: even for express > devices, legacy capabilities can not spill out from > the low 256 bytes: the extended config space has its > own capability list always starting with the express > capability at offset 256. > will just remove this checking & put it all in device-assignment.c >> + >> + /* ensure don't walk off end of config_map[] */ >> + if (offset> (config_size - size)) { > > I prefer not to have () around math here. > > ok. >> + fprintf(stderr, "ERROR: %04x:%02x:%02x.%x " >> + "Attempt to add PCI capability 0x%x at offset 0x%x," >> + "size 0x%x, which exceeds emulated PCI config space 0x%x\n", >> + pci_find_domain(pdev->bus), pci_bus_num(pdev->bus), >> + PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), >> + cap_id, offset, size, config_size); >> + return -EINVAL; >> + } >> >> for (i = offset; i< offset + size; i++) { >> if (pdev->config_map[i]) { >> fprintf(stderr, "ERROR: %04x:%02x:%02x.%x " >> - "Attempt to add PCI capability %x at offset " >> - "%x overlaps existing capability %x at offset %x\n", >> + "Attempt to add PCI capability 0x%x at offset " >> + "0x%x overlaps existing capability 0x%x at offset 0x%x\n", >> pci_find_domain(pdev->bus), pci_bus_num(pdev->bus), >> PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), >> cap_id, offset, pdev->config_map[i], i); ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/2] pci: correct pci config size default for cap version 2 endpoints 2011-07-20 23:46 [PATCH 0/2] pci: config space bounds check and correction Donald Dutile 2011-07-20 23:49 ` [PATCH 1/2] pci: bounds check offsets into config_map Donald Dutile @ 2011-07-20 23:51 ` Donald Dutile 2011-07-21 2:43 ` Alex Williamson 1 sibling, 1 reply; 7+ messages in thread From: Donald Dutile @ 2011-07-20 23:51 UTC (permalink / raw) To: kvm; +Cc: alex.williamson, mst Corrected default size of PCIe Cap Structure from 0x3c to 0x34. 0x34 is min size for version 2 Cap Structure for an endpoint. 0x3c value failed on a real device that aligned this structure at 0xcc, exceeding the size of the config_map[] by 8 bytes. Signed-off-by: Donald Dutile <ddutile@redhat.com> cc: Alex Williamson <alex.williamson@redhat.com> cc: Michael S. Tsirkin <mst@redhat.com> --- hw/device-assignment.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/hw/device-assignment.c b/hw/device-assignment.c index 36ad6b0..1d2ee5d 100644 --- a/hw/device-assignment.c +++ b/hw/device-assignment.c @@ -1422,12 +1422,14 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev) uint8_t version; uint16_t type, devctl, lnkcap, lnksta; uint32_t devcap; - int size = 0x3c; /* version 2 size */ version = pci_get_byte(pci_dev->config + pos + PCI_EXP_FLAGS); version &= PCI_EXP_FLAGS_VERS; if (version == 1) { size = 0x14; + } else if (version == 2) { + /* don't include slot cap/stat/ctrl 2 regs; only support endpoints */ + size = 0x34; } else if (version > 2) { fprintf(stderr, "Unsupported PCI express capability version %d\n", version); ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] pci: correct pci config size default for cap version 2 endpoints 2011-07-20 23:51 ` [PATCH 2/2] pci: correct pci config size default for cap version 2 endpoints Donald Dutile @ 2011-07-21 2:43 ` Alex Williamson 2011-07-21 15:52 ` Don Dutile 0 siblings, 1 reply; 7+ messages in thread From: Alex Williamson @ 2011-07-21 2:43 UTC (permalink / raw) To: Donald Dutile; +Cc: kvm, mst On Wed, 2011-07-20 at 19:51 -0400, Donald Dutile wrote: > Corrected default size of PCIe Cap Structure from 0x3c to 0x34. > 0x34 is min size for version 2 Cap Structure for an endpoint. > > 0x3c value failed on a real device that aligned this > structure at 0xcc, exceeding the size of the config_map[] > by 8 bytes. > > Signed-off-by: Donald Dutile <ddutile@redhat.com> > cc: Alex Williamson <alex.williamson@redhat.com> > cc: Michael S. Tsirkin <mst@redhat.com> > --- > > hw/device-assignment.c | 4 +++- > 1 files changed, 3 insertions(+), 1 deletions(-) > > diff --git a/hw/device-assignment.c b/hw/device-assignment.c > index 36ad6b0..1d2ee5d 100644 > --- a/hw/device-assignment.c > +++ b/hw/device-assignment.c > @@ -1422,12 +1422,14 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev) > uint8_t version; > uint16_t type, devctl, lnkcap, lnksta; > uint32_t devcap; > - int size = 0x3c; /* version 2 size */ > > version = pci_get_byte(pci_dev->config + pos + PCI_EXP_FLAGS); > version &= PCI_EXP_FLAGS_VERS; > if (version == 1) { > size = 0x14; > + } else if (version == 2) { > + /* don't include slot cap/stat/ctrl 2 regs; only support endpoints */ > + size = 0x34; > } else if (version > 2) { > fprintf(stderr, "Unsupported PCI express capability version %d\n", > version); > Does this compile? Where is size defined now? Also whitespace issues with tabs. Alex ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] pci: correct pci config size default for cap version 2 endpoints 2011-07-21 2:43 ` Alex Williamson @ 2011-07-21 15:52 ` Don Dutile 0 siblings, 0 replies; 7+ messages in thread From: Don Dutile @ 2011-07-21 15:52 UTC (permalink / raw) To: Alex Williamson; +Cc: kvm, mst On 07/20/2011 10:43 PM, Alex Williamson wrote: > On Wed, 2011-07-20 at 19:51 -0400, Donald Dutile wrote: >> Corrected default size of PCIe Cap Structure from 0x3c to 0x34. >> 0x34 is min size for version 2 Cap Structure for an endpoint. >> >> 0x3c value failed on a real device that aligned this >> structure at 0xcc, exceeding the size of the config_map[] >> by 8 bytes. >> >> Signed-off-by: Donald Dutile<ddutile@redhat.com> >> cc: Alex Williamson<alex.williamson@redhat.com> >> cc: Michael S. Tsirkin<mst@redhat.com> >> --- >> >> hw/device-assignment.c | 4 +++- >> 1 files changed, 3 insertions(+), 1 deletions(-) >> >> diff --git a/hw/device-assignment.c b/hw/device-assignment.c >> index 36ad6b0..1d2ee5d 100644 >> --- a/hw/device-assignment.c >> +++ b/hw/device-assignment.c >> @@ -1422,12 +1422,14 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev) >> uint8_t version; >> uint16_t type, devctl, lnkcap, lnksta; >> uint32_t devcap; >> - int size = 0x3c; /* version 2 size */ >> >> version = pci_get_byte(pci_dev->config + pos + PCI_EXP_FLAGS); >> version&= PCI_EXP_FLAGS_VERS; >> if (version == 1) { >> size = 0x14; >> + } else if (version == 2) { >> + /* don't include slot cap/stat/ctrl 2 regs; only support endpoints */ >> + size = 0x34; >> } else if (version> 2) { >> fprintf(stderr, "Unsupported PCI express capability version %d\n", >> version); >> > > Does this compile? Where is size defined now? Also whitespace issues > with tabs. > > Alex > doh! during recent workstation upgrade, i forgot to install pciutils-devel; I didn't look at the configure output closely, and now see this file wasn't compiled! thanks for catch. will repost shortly. ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2011-07-21 15:52 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-07-20 23:46 [PATCH 0/2] pci: config space bounds check and correction Donald Dutile 2011-07-20 23:49 ` [PATCH 1/2] pci: bounds check offsets into config_map Donald Dutile 2011-07-21 8:11 ` Michael S. Tsirkin 2011-07-21 15:52 ` Don Dutile 2011-07-20 23:51 ` [PATCH 2/2] pci: correct pci config size default for cap version 2 endpoints Donald Dutile 2011-07-21 2:43 ` Alex Williamson 2011-07-21 15:52 ` Don Dutile
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox