diff mbox series

[v2,1/2] ait-vga: check address before reading configuration bytes

Message ID 20200603202251.1199170-2-ppandit@redhat.com
State New
Headers show
Series Ensure PCI configuration access is within bounds | expand

Commit Message

Prasad Pandit June 3, 2020, 8:22 p.m. UTC
From: Prasad J Pandit <pjp@fedoraproject.org>

While reading PCI configuration bytes, a guest may send an
address towards the end of the configuration space. It may lead
to an OOB access issue. Add check to ensure 'address + size' is
within PCI configuration space.

Reported-by: Ren Ding <rding@gatech.edu>
Reported-by: Hanqing Zhao <hanqing@gatech.edu>
Reported-by: Yi Ren <c4tren@gmail.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
---
 hw/display/ati.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

Update v2: add check to avoid OOB PCI configuration space access
  -> https://lists.gnu.org/archive/html/qemu-devel/2020-06/msg00711.html

Comments

BALATON Zoltan June 3, 2020, 9:58 p.m. UTC | #1
On Thu, 4 Jun 2020, P J P wrote:
> From: Prasad J Pandit <pjp@fedoraproject.org>
>
> While reading PCI configuration bytes, a guest may send an
> address towards the end of the configuration space. It may lead
> to an OOB access issue. Add check to ensure 'address + size' is
> within PCI configuration space.
>
> Reported-by: Ren Ding <rding@gatech.edu>
> Reported-by: Hanqing Zhao <hanqing@gatech.edu>
> Reported-by: Yi Ren <c4tren@gmail.com>
> Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
> ---
> hw/display/ati.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> Update v2: add check to avoid OOB PCI configuration space access
>  -> https://lists.gnu.org/archive/html/qemu-devel/2020-06/msg00711.html
>
> diff --git a/hw/display/ati.c b/hw/display/ati.c
> index bda4a2d816..6671959e5d 100644
> --- a/hw/display/ati.c
> +++ b/hw/display/ati.c
> @@ -384,7 +384,10 @@ static uint64_t ati_mm_read(void *opaque, hwaddr addr, unsigned int size)
>         val = s->regs.crtc_pitch;
>         break;
>     case 0xf00 ... 0xfff:
> -        val = pci_default_read_config(&s->dev, addr - 0xf00, size);
> +        addr = addr - 0xf00;

I'd write this as addr -= 0xf00 but modifying addr here breaks the trace 
print out at end of function so better drop this line and do

if (addr + size <= 0xfff) {

instead. Or is that really (addr + size - 1 <= 0xfff) considering that 
reading the last byte with addr = 0xfff size = 1 should probably be valid.

Regards,
BALATON Zoltan

> +        if (addr + size <= 0xff) {
> +            val = pci_default_read_config(&s->dev, addr, size);
> +        }
>         break;
>     case CUR_OFFSET:
>         val = s->regs.cur_offset;
>
Daniel P. Berrangé June 4, 2020, 8:43 a.m. UTC | #2
Typo: s/ait/ati/

On Thu, Jun 04, 2020 at 01:52:50AM +0530, P J P wrote:
> From: Prasad J Pandit <pjp@fedoraproject.org>
> 
> While reading PCI configuration bytes, a guest may send an
> address towards the end of the configuration space. It may lead
> to an OOB access issue. Add check to ensure 'address + size' is
> within PCI configuration space.

Please include a CVE number for this security flaw if there is
one.

> 
> Reported-by: Ren Ding <rding@gatech.edu>
> Reported-by: Hanqing Zhao <hanqing@gatech.edu>
> Reported-by: Yi Ren <c4tren@gmail.com>
> Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
> ---
>  hw/display/ati.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> Update v2: add check to avoid OOB PCI configuration space access
>   -> https://lists.gnu.org/archive/html/qemu-devel/2020-06/msg00711.html
> 
> diff --git a/hw/display/ati.c b/hw/display/ati.c
> index bda4a2d816..6671959e5d 100644
> --- a/hw/display/ati.c
> +++ b/hw/display/ati.c
> @@ -384,7 +384,10 @@ static uint64_t ati_mm_read(void *opaque, hwaddr addr, unsigned int size)
>          val = s->regs.crtc_pitch;
>          break;
>      case 0xf00 ... 0xfff:
> -        val = pci_default_read_config(&s->dev, addr - 0xf00, size);
> +        addr = addr - 0xf00;
> +        if (addr + size <= 0xff) {
> +            val = pci_default_read_config(&s->dev, addr, size);
> +        }
>          break;
>      case CUR_OFFSET:
>          val = s->regs.cur_offset;
> -- 
> 2.26.2
> 

Regards,
Daniel
Prasad Pandit June 4, 2020, 9:18 a.m. UTC | #3
Hello Phil,

+-- On Thu, 4 Jun 2020, Philippe Mathieu-Daudé wrote --+
| >> @@ -1381,6 +1381,8 @@ uint32_t pci_default_read_config(PCIDevice *d,
| >> +    assert(address + len <= pci_config_size(d));
| 
| Yes, maybe I was not clear while reviewing v1, we need to audit the
| callers and fix them first, then we can safely add the assert here.

That's an elaborate task. Could we please make that into another patch series?

+-- On Thu, 4 Jun 2020, Daniel P. Berrangé wrote --+
| On Thu, Jun 04, 2020 at 01:52:50AM +0530, P J P wrote:
| > While reading PCI configuration bytes, a guest may send an
| > address towards the end of the configuration space. It may lead
| > to an OOB access issue. Add check to ensure 'address + size' is
| > within PCI configuration space.
| 
| Please include a CVE number for this security flaw if there is
| one.

Yes. For now I'll send a revised patch to fix this ati-vga OOB access issue.

Thank you.
--
Prasad J Pandit / Red Hat Product Security Team
8685 545E B54C 486B C6EB 271E E285 8B5A F050 DE8D
Michael S. Tsirkin June 4, 2020, 9:40 a.m. UTC | #4
On Thu, Jun 04, 2020 at 02:48:59PM +0530, P J P wrote:
>   Hello Phil,
> 
> +-- On Thu, 4 Jun 2020, Philippe Mathieu-Daudé wrote --+
> | >> @@ -1381,6 +1381,8 @@ uint32_t pci_default_read_config(PCIDevice *d,
> | >> +    assert(address + len <= pci_config_size(d));
> | 
> | Yes, maybe I was not clear while reviewing v1, we need to audit the
> | callers and fix them first, then we can safely add the assert here.
> 
> That's an elaborate task. Could we please make that into another patch series?

So let's make this a separate patch as defence in depth in case
there are more bugs somewhere. Patch 1 is a CVE fix. Patch 2
is not.

> +-- On Thu, 4 Jun 2020, Daniel P. Berrangé wrote --+
> | On Thu, Jun 04, 2020 at 01:52:50AM +0530, P J P wrote:
> | > While reading PCI configuration bytes, a guest may send an
> | > address towards the end of the configuration space. It may lead
> | > to an OOB access issue. Add check to ensure 'address + size' is
> | > within PCI configuration space.
> | 
> | Please include a CVE number for this security flaw if there is
> | one.
> 
> Yes. For now I'll send a revised patch to fix this ati-vga OOB access issue.
> 
> Thank you.
> --
> Prasad J Pandit / Red Hat Product Security Team
> 8685 545E B54C 486B C6EB 271E E285 8B5A F050 DE8D
diff mbox series

Patch

diff --git a/hw/display/ati.c b/hw/display/ati.c
index bda4a2d816..6671959e5d 100644
--- a/hw/display/ati.c
+++ b/hw/display/ati.c
@@ -384,7 +384,10 @@  static uint64_t ati_mm_read(void *opaque, hwaddr addr, unsigned int size)
         val = s->regs.crtc_pitch;
         break;
     case 0xf00 ... 0xfff:
-        val = pci_default_read_config(&s->dev, addr - 0xf00, size);
+        addr = addr - 0xf00;
+        if (addr + size <= 0xff) {
+            val = pci_default_read_config(&s->dev, addr, size);
+        }
         break;
     case CUR_OFFSET:
         val = s->regs.cur_offset;