aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAxel Lin <axel.lin@gmail.com>2010-07-20 18:19:53 -0400
committerMatthew Garrett <mjg@redhat.com>2010-08-03 09:49:04 -0400
commit7677fbdff16f5b817bc3dc5d194a8b3350f8f9cb (patch)
tree2086eff81fa49d9b9a5ab569a7b867f30c7d24d6
parent669048639ca6d3fdfb2e75dd77b8f49434d57625 (diff)
acer-wmi: fix memory leaks in wmab_execute error path
When acpi_evaluate_object() is passed ACPI_ALLOCATE_BUFFER, the caller must kfree the returned buffer if AE_OK is returned. Call Trace: wmab_execute -> wmi_evaluate_method -> acpi_evaluate_object Thus if callers of wmab_execute() pass ACPI_ALLOCATE_BUFFER, the return buffer must be kfreed if wmab_execute return AE_OK. [akpm@linux-foundation.org: avoid multiple return points, remove unneeded cast, remove unneeded initialisation of `status'] Signed-off-by: Axel Lin <axel.lin@gmail.com> Acked-by: Carlos Corbacho <carlos@strangeworlds.co.uk> Cc: Matthew Garrett <mjg@redhat.com> Cc: Thomas Renninger <trenn@suse.de> Cc: Alan Jenkins <alan-jenkins@tuffmail.co.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Matthew Garrett <mjg@redhat.com>
-rw-r--r--drivers/platform/x86/acer-wmi.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index 652ca1800a0a..b06678660956 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -555,6 +555,7 @@ static acpi_status AMW0_find_mailled(void)
555 obj->buffer.length == sizeof(struct wmab_ret)) { 555 obj->buffer.length == sizeof(struct wmab_ret)) {
556 ret = *((struct wmab_ret *) obj->buffer.pointer); 556 ret = *((struct wmab_ret *) obj->buffer.pointer);
557 } else { 557 } else {
558 kfree(out.pointer);
558 return AE_ERROR; 559 return AE_ERROR;
559 } 560 }
560 561
@@ -570,7 +571,7 @@ static acpi_status AMW0_set_capabilities(void)
570{ 571{
571 struct wmab_args args; 572 struct wmab_args args;
572 struct wmab_ret ret; 573 struct wmab_ret ret;
573 acpi_status status = AE_OK; 574 acpi_status status;
574 struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL }; 575 struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };
575 union acpi_object *obj; 576 union acpi_object *obj;
576 577
@@ -593,12 +594,13 @@ static acpi_status AMW0_set_capabilities(void)
593 if (ACPI_FAILURE(status)) 594 if (ACPI_FAILURE(status))
594 return status; 595 return status;
595 596
596 obj = (union acpi_object *) out.pointer; 597 obj = out.pointer;
597 if (obj && obj->type == ACPI_TYPE_BUFFER && 598 if (obj && obj->type == ACPI_TYPE_BUFFER &&
598 obj->buffer.length == sizeof(struct wmab_ret)) { 599 obj->buffer.length == sizeof(struct wmab_ret)) {
599 ret = *((struct wmab_ret *) obj->buffer.pointer); 600 ret = *((struct wmab_ret *) obj->buffer.pointer);
600 } else { 601 } else {
601 return AE_ERROR; 602 status = AE_ERROR;
603 goto out;
602 } 604 }
603 605
604 if (ret.eax & 0x1) 606 if (ret.eax & 0x1)
@@ -607,23 +609,26 @@ static acpi_status AMW0_set_capabilities(void)
607 args.ebx = 2 << 8; 609 args.ebx = 2 << 8;
608 args.ebx |= ACER_AMW0_BLUETOOTH_MASK; 610 args.ebx |= ACER_AMW0_BLUETOOTH_MASK;
609 611
612 /*
613 * It's ok to use existing buffer for next wmab_execute call.
614 * But we need to kfree(out.pointer) if next wmab_execute fail.
615 */
610 status = wmab_execute(&args, &out); 616 status = wmab_execute(&args, &out);
611 if (ACPI_FAILURE(status)) 617 if (ACPI_FAILURE(status))
612 return status; 618 goto out;
613 619
614 obj = (union acpi_object *) out.pointer; 620 obj = (union acpi_object *) out.pointer;
615 if (obj && obj->type == ACPI_TYPE_BUFFER 621 if (obj && obj->type == ACPI_TYPE_BUFFER
616 && obj->buffer.length == sizeof(struct wmab_ret)) { 622 && obj->buffer.length == sizeof(struct wmab_ret)) {
617 ret = *((struct wmab_ret *) obj->buffer.pointer); 623 ret = *((struct wmab_ret *) obj->buffer.pointer);
618 } else { 624 } else {
619 return AE_ERROR; 625 status = AE_ERROR;
626 goto out;
620 } 627 }
621 628
622 if (ret.eax & 0x1) 629 if (ret.eax & 0x1)
623 interface->capability |= ACER_CAP_BLUETOOTH; 630 interface->capability |= ACER_CAP_BLUETOOTH;
624 631
625 kfree(out.pointer);
626
627 /* 632 /*
628 * This appears to be safe to enable, since all Wistron based laptops 633 * This appears to be safe to enable, since all Wistron based laptops
629 * appear to use the same EC register for brightness, even if they 634 * appear to use the same EC register for brightness, even if they
@@ -632,7 +637,10 @@ static acpi_status AMW0_set_capabilities(void)
632 if (quirks->brightness >= 0) 637 if (quirks->brightness >= 0)
633 interface->capability |= ACER_CAP_BRIGHTNESS; 638 interface->capability |= ACER_CAP_BRIGHTNESS;
634 639
635 return AE_OK; 640 status = AE_OK;
641out:
642 kfree(out.pointer);
643 return status;
636} 644}
637 645
638static struct wmi_interface AMW0_interface = { 646static struct wmi_interface AMW0_interface = {