From 94765f19525192de30cdbec1ec7b063273242e29 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Sat, 10 Nov 2012 12:17:46 +0100 Subject: [PATCH] Improve error checking, do not leak memory A reference to pci_dev was always kept on failure (which is rare, but it could happen if the bug is fixed or BIOS is updated). The handle name was also always leaked, this is now corrected too. --- acpi-handle-hack.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/acpi-handle-hack.c b/acpi-handle-hack.c index 08b825b..07fd838 100644 --- a/acpi-handle-hack.c +++ b/acpi-handle-hack.c @@ -72,20 +72,35 @@ static int __init hack_apply(void) { orig_handle = DEVICE_ACPI_HANDLE(&dis_dev->dev); if (!orig_handle) { pr_err("No ACPI handle found for discrete video card\n"); - return -ENODEV; + goto free_dev; + } + if (ACPI_FAILURE(acpi_get_name(orig_handle, ACPI_SINGLE_NAME, &buf))) { + pr_err("Could not acquire name for discrete video card\n"); + goto free_dev; } - acpi_get_name(orig_handle, ACPI_SINGLE_NAME, &buf); if (strcmp((char *)buf.pointer, "PEGP") == 0) { pr_err("Handle has already been changed to PEGP\n"); - return -ENODEV; + goto free_name; } /* \_SB.PCI0.PEG0.VGA_ -> \_SB.PCI0.PEG0.PEGP */ - acpi_get_parent(orig_handle, &tmp_handle); - acpi_get_handle(tmp_handle, "PEGP", &new_handle); + if (ACPI_FAILURE(acpi_get_parent(orig_handle, &tmp_handle))) { + pr_err("No parent device found for %s\n", (char *)buf.pointer); + goto free_name; + } + if (ACPI_FAILURE(acpi_get_handle(tmp_handle, "PEGP", &new_handle))) { + pr_err("No PEGP handle found on %s\n", (char *)buf.pointer); + goto free_name; + } pr_info("Setting new ACPI handle for discrete video card\n"); dev_set_acpi_handle(dis_dev, new_handle); + kfree(buf.pointer); pci_dev_put(dis_dev); return 0; +free_name: + kfree(buf.pointer); +free_dev: + pci_dev_put(dis_dev); + return -ENODEV; } static void __exit hack_undo(void) {