Prev: [patch 059/123] p54usb: Add the USB ID for Belkin (Accton) FD7050E ver 1010ec
Next: [patch 053/123] Driver-Core: devtmpfs - reset inode permissions before unlinking
From: Greg KH on 12 Mar 2010 20:30 2.6.33-stable review patch. If anyone has any objections, please let me know. ----------------- From: Thomas Gleixner <tglx(a)linutronix.de> commit bb8d41330ce27edb91adb6922d3f8e1a8923f727 upstream. commit ff097ddd4 (x86/PCI: MMCONFIG: manage pci_mmcfg_region as a list, not a table) introduced a nasty memory corruption when pci_mmcfg_list is empty. pci_mmcfg_check_end_bus_number() dereferences pci_mmcfg_list.prev even when the list is empty. The following write hits some variable near to pci_mmcfg_list. Further down a similar problem exists, where cfg->list.next is dereferenced unconditionally and a comparison with some variable near to pci_mmcfg_list happens. Add a check for the last element into the for_each_entry() loop and remove all the other crappy logic which is just a leftover of the old array based code which was replaced by the list conversion. Reported-by: Ingo Molnar <mingo(a)elte.hu> Signed-off-by: Thomas Gleixner <tglx(a)linutronix.de> Cc: Bjorn Helgaas <bjorn.helgaas(a)hp.com> Cc: Yinghai Lu <yinghai(a)kernel.org> Signed-off-by: Jesse Barnes <jbarnes(a)virtuousgeek.org> Signed-off-by: Greg Kroah-Hartman <gregkh(a)suse.de> --- arch/x86/pci/mmconfig-shared.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c @@ -303,22 +303,17 @@ static void __init pci_mmcfg_check_end_b { struct pci_mmcfg_region *cfg, *cfgx; - /* last one*/ - cfg = list_entry(pci_mmcfg_list.prev, typeof(*cfg), list); - if (cfg) - if (cfg->end_bus < cfg->start_bus) - cfg->end_bus = 255; - - if (list_is_singular(&pci_mmcfg_list)) - return; - - /* don't overlap please */ + /* Fixup overlaps */ list_for_each_entry(cfg, &pci_mmcfg_list, list) { if (cfg->end_bus < cfg->start_bus) cfg->end_bus = 255; + /* Don't access the list head ! */ + if (cfg->list.next == &pci_mmcfg_list) + break; + cfgx = list_entry(cfg->list.next, typeof(*cfg), list); - if (cfg != cfgx && cfg->end_bus >= cfgx->start_bus) + if (cfg->end_bus >= cfgx->start_bus) cfg->end_bus = cfgx->start_bus - 1; } } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo(a)vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/ |