aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/pci_link.c
diff options
context:
space:
mode:
authorBjorn Helgaas <bjorn.helgaas@hp.com>2008-08-01 15:58:17 -0600
committerAndi Kleen <ak@linux.intel.com>2008-08-15 03:17:07 +0200
commitfa46d3526461e8aa7c0fb39cc1b98ac656695a43 (patch)
tree0094d2a1ff5782cdf6f65dcdf8c7c54e0e1bded9 /drivers/acpi/pci_link.c
parentb635acec48bcaa9183fcbf4e3955616b0d4119b5 (diff)
downloadkernel_samsung_smdk4412-fa46d3526461e8aa7c0fb39cc1b98ac656695a43.zip
kernel_samsung_smdk4412-fa46d3526461e8aa7c0fb39cc1b98ac656695a43.tar.gz
kernel_samsung_smdk4412-fa46d3526461e8aa7c0fb39cc1b98ac656695a43.tar.bz2
ACPI: bounds check IRQ to prevent memory corruption
acpi_penalize_isa_irq() should validate irq before using it to index the acpi_irq_penalty[] table. Here's the path I'm concerned about: pnpacpi_parse_allocated_irqresource() { ... irq = acpi_register_gsi(gsi, triggering, polarity); if (irq >= 0) pcibios_penalize_isa_irq(irq, 1); There's no guarantee that acpi_register_gsi() will return an IRQ within the bounds of acpi_irq_penalty[]. I have not seen a failure I can attribute to this. However, ACPI_MAX_IRQS is only 256, and I'm pretty sure ia64 can have IRQs larger than that. I think this should go in 2.6.27. Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com> Signed-off-by: Andi Kleen <ak@linux.intel.com>
Diffstat (limited to 'drivers/acpi/pci_link.c')
-rw-r--r--drivers/acpi/pci_link.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 89f3b2a..cf47805 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -849,7 +849,7 @@ static int __init acpi_irq_penalty_update(char *str, int used)
if (irq < 0)
continue;
- if (irq >= ACPI_MAX_IRQS)
+ if (irq >= ARRAY_SIZE(acpi_irq_penalty))
continue;
if (used)
@@ -872,10 +872,12 @@ static int __init acpi_irq_penalty_update(char *str, int used)
*/
void acpi_penalize_isa_irq(int irq, int active)
{
- if (active)
- acpi_irq_penalty[irq] += PIRQ_PENALTY_ISA_USED;
- else
- acpi_irq_penalty[irq] += PIRQ_PENALTY_PCI_USING;
+ if (irq >= 0 && irq < ARRAY_SIZE(acpi_irq_penalty)) {
+ if (active)
+ acpi_irq_penalty[irq] += PIRQ_PENALTY_ISA_USED;
+ else
+ acpi_irq_penalty[irq] += PIRQ_PENALTY_PCI_USING;
+ }
}
/*