Commit 9a0a3597 authored by Lv Zheng's avatar Lv Zheng Committed by Rafael J. Wysocki

ACPICA: Resources: Fix loop termination for the get AML length function.

The loop terminates on a NULL resource pointer, which can never
happen since the loop simply increments a valid resource pointer.
This fix changes the loop to terminate on an end-of-buffer condition.

Problem can be seen by callers to AcpiSetCurrentResources with an
invalid or corrupted resource descriptor; or a resource descriptor
without an END_TAG descriptor.

(refined by Bob Moore)
Reported-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: default avatarLv Zheng <lv.zheng@intel.com>
Signed-off-by: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent c38f671e
...@@ -184,7 +184,7 @@ acpi_rs_create_resource_list(union acpi_operand_object *aml_buffer, ...@@ -184,7 +184,7 @@ acpi_rs_create_resource_list(union acpi_operand_object *aml_buffer,
struct acpi_buffer *output_buffer); struct acpi_buffer *output_buffer);
acpi_status acpi_status
acpi_rs_create_aml_resources(struct acpi_resource *linked_list_buffer, acpi_rs_create_aml_resources(struct acpi_buffer *resource_list,
struct acpi_buffer *output_buffer); struct acpi_buffer *output_buffer);
acpi_status acpi_status
...@@ -227,8 +227,8 @@ acpi_rs_get_list_length(u8 * aml_buffer, ...@@ -227,8 +227,8 @@ acpi_rs_get_list_length(u8 * aml_buffer,
u32 aml_buffer_length, acpi_size * size_needed); u32 aml_buffer_length, acpi_size * size_needed);
acpi_status acpi_status
acpi_rs_get_aml_length(struct acpi_resource *linked_list_buffer, acpi_rs_get_aml_length(struct acpi_resource *resource_list,
acpi_size * size_needed); acpi_size resource_list_size, acpi_size * size_needed);
acpi_status acpi_status
acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
......
...@@ -174,6 +174,7 @@ acpi_rs_stream_option_length(u32 resource_length, ...@@ -174,6 +174,7 @@ acpi_rs_stream_option_length(u32 resource_length,
* FUNCTION: acpi_rs_get_aml_length * FUNCTION: acpi_rs_get_aml_length
* *
* PARAMETERS: resource - Pointer to the resource linked list * PARAMETERS: resource - Pointer to the resource linked list
* resource_list_size - Size of the resource linked list
* size_needed - Where the required size is returned * size_needed - Where the required size is returned
* *
* RETURN: Status * RETURN: Status
...@@ -185,16 +186,20 @@ acpi_rs_stream_option_length(u32 resource_length, ...@@ -185,16 +186,20 @@ acpi_rs_stream_option_length(u32 resource_length,
******************************************************************************/ ******************************************************************************/
acpi_status acpi_status
acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed) acpi_rs_get_aml_length(struct acpi_resource *resource,
acpi_size resource_list_size, acpi_size * size_needed)
{ {
acpi_size aml_size_needed = 0; acpi_size aml_size_needed = 0;
struct acpi_resource *resource_end;
acpi_rs_length total_size; acpi_rs_length total_size;
ACPI_FUNCTION_TRACE(rs_get_aml_length); ACPI_FUNCTION_TRACE(rs_get_aml_length);
/* Traverse entire list of internal resource descriptors */ /* Traverse entire list of internal resource descriptors */
while (resource) { resource_end =
ACPI_ADD_PTR(struct acpi_resource, resource, resource_list_size);
while (resource < resource_end) {
/* Validate the descriptor type */ /* Validate the descriptor type */
......
...@@ -418,22 +418,21 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, ...@@ -418,22 +418,21 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
* *
* FUNCTION: acpi_rs_create_aml_resources * FUNCTION: acpi_rs_create_aml_resources
* *
* PARAMETERS: linked_list_buffer - Pointer to the resource linked list * PARAMETERS: resource_list - Pointer to the resource list buffer
* output_buffer - Pointer to the user's buffer * output_buffer - Where the AML buffer is returned
* *
* RETURN: Status AE_OK if okay, else a valid acpi_status code. * RETURN: Status AE_OK if okay, else a valid acpi_status code.
* If the output_buffer is too small, the error will be * If the output_buffer is too small, the error will be
* AE_BUFFER_OVERFLOW and output_buffer->Length will point * AE_BUFFER_OVERFLOW and output_buffer->Length will point
* to the size buffer needed. * to the size buffer needed.
* *
* DESCRIPTION: Takes the linked list of device resources and * DESCRIPTION: Converts a list of device resources to an AML bytestream
* creates a bytestream to be used as input for the * to be used as input for the _SRS control method.
* _SRS control method.
* *
******************************************************************************/ ******************************************************************************/
acpi_status acpi_status
acpi_rs_create_aml_resources(struct acpi_resource *linked_list_buffer, acpi_rs_create_aml_resources(struct acpi_buffer *resource_list,
struct acpi_buffer *output_buffer) struct acpi_buffer *output_buffer)
{ {
acpi_status status; acpi_status status;
...@@ -441,16 +440,16 @@ acpi_rs_create_aml_resources(struct acpi_resource *linked_list_buffer, ...@@ -441,16 +440,16 @@ acpi_rs_create_aml_resources(struct acpi_resource *linked_list_buffer,
ACPI_FUNCTION_TRACE(rs_create_aml_resources); ACPI_FUNCTION_TRACE(rs_create_aml_resources);
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "LinkedListBuffer = %p\n", /* Params already validated, no need to re-validate here */
linked_list_buffer));
/* ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ResourceList Buffer = %p\n",
* Params already validated, so we don't re-validate here resource_list->pointer));
*
* Pass the linked_list_buffer into a module that calculates /* Get the buffer size needed for the AML byte stream */
* the buffer size needed for the byte stream.
*/ status = acpi_rs_get_aml_length(resource_list->pointer,
status = acpi_rs_get_aml_length(linked_list_buffer, &aml_size_needed); resource_list->length,
&aml_size_needed);
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "AmlSizeNeeded=%X, %s\n", ACPI_DEBUG_PRINT((ACPI_DB_INFO, "AmlSizeNeeded=%X, %s\n",
(u32)aml_size_needed, acpi_format_exception(status))); (u32)aml_size_needed, acpi_format_exception(status)));
...@@ -467,10 +466,9 @@ acpi_rs_create_aml_resources(struct acpi_resource *linked_list_buffer, ...@@ -467,10 +466,9 @@ acpi_rs_create_aml_resources(struct acpi_resource *linked_list_buffer,
/* Do the conversion */ /* Do the conversion */
status = status = acpi_rs_convert_resources_to_aml(resource_list->pointer,
acpi_rs_convert_resources_to_aml(linked_list_buffer, aml_size_needed,
aml_size_needed, output_buffer->pointer);
output_buffer->pointer);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
......
...@@ -753,7 +753,7 @@ acpi_rs_set_srs_method_data(struct acpi_namespace_node *node, ...@@ -753,7 +753,7 @@ acpi_rs_set_srs_method_data(struct acpi_namespace_node *node,
* Convert the linked list into a byte stream * Convert the linked list into a byte stream
*/ */
buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
status = acpi_rs_create_aml_resources(in_buffer->pointer, &buffer); status = acpi_rs_create_aml_resources(in_buffer, &buffer);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
goto cleanup; goto cleanup;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment