Module Name: src Committed By: jruoho Date: Tue Jan 5 13:32:49 UTC 2010
Modified Files: src/sys/arch/x86/x86: mpacpi.c Log Message: Fix several possible memory leaks in mpacpi_derive_bus(). ok pgoyette@, jmcneill@ To generate a diff of this commit: cvs rdiff -u -r1.80 -r1.81 src/sys/arch/x86/x86/mpacpi.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/x86/x86/mpacpi.c diff -u src/sys/arch/x86/x86/mpacpi.c:1.80 src/sys/arch/x86/x86/mpacpi.c:1.81 --- src/sys/arch/x86/x86/mpacpi.c:1.80 Tue Jan 5 13:20:30 2010 +++ src/sys/arch/x86/x86/mpacpi.c Tue Jan 5 13:32:49 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: mpacpi.c,v 1.80 2010/01/05 13:20:30 mbalmer Exp $ */ +/* $NetBSD: mpacpi.c,v 1.81 2010/01/05 13:32:49 jruoho Exp $ */ /* * Copyright (c) 2003 Wasabi Systems, Inc. @@ -36,7 +36,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: mpacpi.c,v 1.80 2010/01/05 13:20:30 mbalmer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mpacpi.c,v 1.81 2010/01/05 13:32:49 jruoho Exp $"); #include "acpica.h" #include "opt_acpi.h" @@ -545,22 +545,23 @@ pcitag_t tag; int bus; - bus = -1; TAILQ_INIT(&dev_list); /* first, search parent root bus */ for (current = handle;; current = parent) { rv = AcpiGetObjectInfo(current, &devinfo); if (ACPI_FAILURE(rv)) - return -1; + goto out; /* add this device to the list only if it's active */ if ((devinfo->Valid & ACPI_VALID_STA) == 0 || (devinfo->CurrentStatus & ACPI_STA_OK) == ACPI_STA_OK) { ACPI_FREE(devinfo); dev = kmem_zalloc(sizeof(struct ac_dev), KM_SLEEP); - if (dev == NULL) - return -1; + if (dev == NULL) { + rv = AE_NO_MEMORY; + goto out; + } dev->handle = current; TAILQ_INSERT_HEAD(&dev_list, dev, list); } else @@ -568,16 +569,15 @@ rv = AcpiGetParent(current, &parent); if (ACPI_FAILURE(rv)) - return -1; + goto out; rv = AcpiGetObjectInfo(parent, &devinfo); if (ACPI_FAILURE(rv)) - return -1; + goto out; if (acpi_match_hid(devinfo, pciroot_hid)) { - rv = mpacpi_get_bbn(acpi, parent, &bus); - if (ACPI_FAILURE(rv)) - bus = 0; + (void)mpacpi_get_bbn(acpi, parent, &bus); + ACPI_FREE(devinfo); break; } @@ -590,8 +590,10 @@ */ TAILQ_FOREACH(dev, &dev_list, list) { rv = acpi_eval_integer(dev->handle, METHOD_NAME__ADR, &val); - if (ACPI_FAILURE(rv) || val == 0xffffffff) - return -1; + if (ACPI_FAILURE(rv) || val == 0xffffffff) { + rv = AE_ERROR; + goto out; + } tag = pci_make_tag(acpi->sc_pc, bus, ACPI_HIWORD(val), ACPI_LOWORD(val)); @@ -599,20 +601,25 @@ /* check if this device exists */ dvid = pci_conf_read(acpi->sc_pc, tag, PCI_ID_REG); if (PCI_VENDOR(dvid) == PCI_VENDOR_INVALID || - PCI_VENDOR(dvid) == 0) - return -1; + PCI_VENDOR(dvid) == 0) { + rv = AE_NOT_EXIST; + goto out; + } /* check if this is a bridge device */ class = pci_conf_read(acpi->sc_pc, tag, PCI_CLASS_REG); if (PCI_CLASS(class) != PCI_CLASS_BRIDGE || - PCI_SUBCLASS(class) != PCI_SUBCLASS_BRIDGE_PCI) - return -1; + PCI_SUBCLASS(class) != PCI_SUBCLASS_BRIDGE_PCI) { + rv = AE_TYPE; + goto out; + } /* if this is a bridge, get secondary bus */ binf = pci_conf_read(acpi->sc_pc, tag, PPB_REG_BUSINFO); bus = PPB_BUSINFO_SECONDARY(binf); } +out: /* cleanup */ while (!TAILQ_EMPTY(&dev_list)) { dev = TAILQ_FIRST(&dev_list); @@ -620,6 +627,9 @@ kmem_free(dev, sizeof(struct ac_dev)); } + if (ACPI_FAILURE(rv)) + bus = -1; + return bus; }