2007-11-01 08:19:52

by Yinghai Lu

[permalink] [raw]
Subject: [PATCH] x86: check boundary in count/setup_resource called by get_current_resources

[PATCH] x86: check boundary in count/setup_resource called by get_current_resources

need to check info->res_num less than PCI_BUS_NUM_RESOURCES, so
info->bus->resource[info->res_num] = res will not beyond of bus resource array
when acpi resutrn too many resource entries.

Signed-off-by: Yinghai Lu <[email protected]>

Index: linux-2.6/arch/x86/pci/acpi.c
===================================================================
--- linux-2.6.orig/arch/x86/pci/acpi.c
+++ linux-2.6/arch/x86/pci/acpi.c
@@ -77,9 +77,13 @@ count_resource(struct acpi_resource *acp
struct acpi_resource_address64 addr;
acpi_status status;

+ if (info->res_num >= PCI_BUS_NUM_RESOURCES)
+ return AE_OK;
+
status = resource_to_addr(acpi_res, &addr);
if (ACPI_SUCCESS(status))
info->res_num++;
+
return AE_OK;
}

@@ -93,6 +97,9 @@ setup_resource(struct acpi_resource *acp
unsigned long flags;
struct resource *root;

+ if (info->res_num >= PCI_BUS_NUM_RESOURCES)
+ return AE_OK;
+
status = resource_to_addr(acpi_res, &addr);
if (!ACPI_SUCCESS(status))
return AE_OK;


2007-11-01 08:33:42

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH] x86: check boundary in count/setup_resource called by get_current_resources

On Thu, 01 Nov 2007 01:20:29 -0700 Yinghai Lu <[email protected]> wrote:

> [PATCH] x86: check boundary in count/setup_resource called by get_current_resources
>
> need to check info->res_num less than PCI_BUS_NUM_RESOURCES, so
> info->bus->resource[info->res_num] = res will not beyond of bus resource array
> when acpi resutrn too many resource entries.
>

Isn't this a bit of a problem? It sounds like PCI_BUS_NUM_RESOURCES is to
small for that system? If so, some sort of dynamic allocation might be
needed.

>
> Index: linux-2.6/arch/x86/pci/acpi.c
> ===================================================================
> --- linux-2.6.orig/arch/x86/pci/acpi.c
> +++ linux-2.6/arch/x86/pci/acpi.c
> @@ -77,9 +77,13 @@ count_resource(struct acpi_resource *acp
> struct acpi_resource_address64 addr;
> acpi_status status;
>
> + if (info->res_num >= PCI_BUS_NUM_RESOURCES)
> + return AE_OK;
> +
> status = resource_to_addr(acpi_res, &addr);
> if (ACPI_SUCCESS(status))
> info->res_num++;
> +
> return AE_OK;
> }

grump. I don't know why people like a blank line before `return': it's
just a waste of screen space. And the surrounding code in
arch/x86/pci/acpi.c doesn't do this either.

> @@ -93,6 +97,9 @@ setup_resource(struct acpi_resource *acp
> unsigned long flags;
> struct resource *root;
>
> + if (info->res_num >= PCI_BUS_NUM_RESOURCES)
> + return AE_OK;

And should we really be silently ignoring this problem? Should we at least
report it?

> status = resource_to_addr(acpi_res, &addr);
> if (!ACPI_SUCCESS(status))
> return AE_OK;
>

2007-11-01 18:03:52

by Yinghai Lu

[permalink] [raw]
Subject: Re: [PATCH] x86: check boundary in count/setup_resource called by get_current_resources

Andrew Morton wrote:
> On Thu, 01 Nov 2007 01:20:29 -0700 Yinghai Lu <[email protected]> wrote:
>
>> [PATCH] x86: check boundary in count/setup_resource called by get_current_resources
>>
>> need to check info->res_num less than PCI_BUS_NUM_RESOURCES, so
>> info->bus->resource[info->res_num] = res will not beyond of bus resource array
>> when acpi resutrn too many resource entries.
>>
>
> Isn't this a bit of a problem? It sounds like PCI_BUS_NUM_RESOURCES is to
> small for that system? If so, some sort of dynamic allocation might be
> needed.

sound reasonable...
i have one local patch for amd64 that will get resources from pci conf. and it will use all 8 slots for bus 0.
and transparent bus under it only can copy 5 of them.

YH

2007-11-01 19:13:20

by Gary Hade

[permalink] [raw]
Subject: Re: [PATCH] x86: check boundary in count/setup_resource called by get_current_resources

On Thu, Nov 01, 2007 at 01:32:39AM -0700, Andrew Morton wrote:
> On Thu, 01 Nov 2007 01:20:29 -0700 Yinghai Lu <[email protected]> wrote:
>
> > [PATCH] x86: check boundary in count/setup_resource called by get_current_resources
> >
> > need to check info->res_num less than PCI_BUS_NUM_RESOURCES, so
> > info->bus->resource[info->res_num] = res will not beyond of bus resource array
> > when acpi resutrn too many resource entries.
> >
>
> Isn't this a bit of a problem? It sounds like PCI_BUS_NUM_RESOURCES is to
> small for that system? If so, some sort of dynamic allocation might be
> needed.

I should have considered the possible resource array overrun
when I created these functions. I had assumed (apparently
incorrectly) that the old PCI_BUS_NUM_RESOURCES value of 4
was based on a spec defined limit on the maximum number of
resources that _CRS can return.

I recently noticed the potential overrun myself while backporting
the code to kernel source where PCI_BUS_NUM_RESOURCES was initially
defined as 4. This happened on a system where the _CRS associated
with one of the root bridges returned 5 resources with the 5th causing
a write beyond the end of the array. Increasing PCI_BUS_NUM_RESOURCES
to the current value of 8 eliminated the overrun that I experienced
but after discovering that there is apparently no limit on the
number of resources that _CRS can return I had intended to post
a change similar to what Yinghai Lu is proposing.

With the current PCI_BUS_NUM_RESOURCES value, _CRS can return
up to 8 resources before the pci_bus resource array is totally
saturated but it should be noted that if a transparent bridge
is present below the root bridge it's child bus will only see
the first 5 resources.

The current fixed pci_bus resource array size of 8 is adequate
(for storing _CRS returned resource and visibility across
transparent bridges) on those systems that I work on but without
a bound on the number of resources returned by _CRS some sort
of dynamic allocation certainly makes sense.

Note that exposure to this issue is currently limited to those
that use the 'pci=use_crs' kernel option.

Gary

--
Gary Hade
System x Enablement
IBM Linux Technology Center
503-578-4503 IBM T/L: 775-4503
[email protected]
http://www.ibm.com/linux/ltc

2007-11-01 20:10:57

by Gary Hade

[permalink] [raw]
Subject: Re: [PATCH] x86: check boundary in count/setup_resource called by get_current_resources

On Thu, Nov 01, 2007 at 11:06:18AM -0700, Yinghai Lu wrote:
> Andrew Morton wrote:
> >On Thu, 01 Nov 2007 01:20:29 -0700 Yinghai Lu <[email protected]> wrote:
> >
> >>[PATCH] x86: check boundary in count/setup_resource called by
> >>get_current_resources
> >>
> >>need to check info->res_num less than PCI_BUS_NUM_RESOURCES, so
> >>info->bus->resource[info->res_num] = res will not beyond of bus resource
> >>array
> >>when acpi resutrn too many resource entries.
> >>
> >
> >Isn't this a bit of a problem? It sounds like PCI_BUS_NUM_RESOURCES is to
> >small for that system? If so, some sort of dynamic allocation might be
> >needed.
>
> sound reasonable...
> i have one local patch for amd64 that will get resources from pci conf. and
> it will use all 8 slots for bus 0.
> and transparent bus under it only can copy 5 of them.

Yea, with the current fixed size pci_bus resource array
I believe you would need to increase PCI_BUS_NUM_RESOURCES
from 8 to 11 for the transparent bridge child bus to get
all 8 _CRS returned resources.

Gary

--
Gary Hade
System x Enablement
IBM Linux Technology Center
503-578-4503 IBM T/L: 775-4503
[email protected]
http://www.ibm.com/linux/ltc