Skip to content

Commit

Permalink
ACPI / ACPICA: Avoid crashing if _PRW is defined for the root object
Browse files Browse the repository at this point in the history
Some ACPI BIOSes define _PRW for the root object which causes
acpi_setup_gpe_for_wake() to crash when trying to dereference the
bogus device_node pointer.  Avoid the crash by checking if
wake_device is not the root object before attempting to set up the
"implicit notify" mechanism for it.

The problem was introduced by commit bba63a2
(ACPICA: Implicit notify support) that added the wake_device argument
to acpi_setup_gpe_for_wake().

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
  • Loading branch information
Rafael J. Wysocki committed Feb 12, 2011
1 parent 100b33c commit 2d55951
Showing 1 changed file with 26 additions and 23 deletions.
49 changes: 26 additions & 23 deletions drivers/acpi/acpica/evxfgpe.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,37 +212,40 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device,
return_ACPI_STATUS(AE_BAD_PARAMETER);
}

/* Validate wake_device is of type Device */

device_node = ACPI_CAST_PTR(struct acpi_namespace_node, wake_device);
if (device_node->type != ACPI_TYPE_DEVICE) {
return_ACPI_STATUS(AE_BAD_PARAMETER);
}

flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);

/* Ensure that we have a valid GPE number */

gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
if (gpe_event_info) {
/*
* If there is no method or handler for this GPE, then the
* wake_device will be notified whenever this GPE fires (aka
* "implicit notify") Note: The GPE is assumed to be
* level-triggered (for windows compatibility).
*/
if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
ACPI_GPE_DISPATCH_NONE) {
gpe_event_info->flags =
(ACPI_GPE_DISPATCH_NOTIFY |
ACPI_GPE_LEVEL_TRIGGERED);
gpe_event_info->dispatch.device_node = device_node;
}
if (!gpe_event_info) {
goto unlock_and_exit;
}

/*
* If there is no method or handler for this GPE, then the
* wake_device will be notified whenever this GPE fires (aka
* "implicit notify") Note: The GPE is assumed to be
* level-triggered (for windows compatibility).
*/
if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
ACPI_GPE_DISPATCH_NONE) && (wake_device != ACPI_ROOT_OBJECT)) {

gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
status = AE_OK;
/* Validate wake_device is of type Device */

device_node = ACPI_CAST_PTR(struct acpi_namespace_node,
wake_device);
if (device_node->type != ACPI_TYPE_DEVICE) {
goto unlock_and_exit;
}
gpe_event_info->flags = (ACPI_GPE_DISPATCH_NOTIFY |
ACPI_GPE_LEVEL_TRIGGERED);
gpe_event_info->dispatch.device_node = device_node;
}

gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
status = AE_OK;

unlock_and_exit:
acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
return_ACPI_STATUS(status);
}
Expand Down

0 comments on commit 2d55951

Please sign in to comment.