]> pilppa.com Git - linux-2.6-omap-h63xx.git/commitdiff
ACPICA: Fix for fault if Load() fails
authorBob Moore <robert.moore@intel.com>
Thu, 10 Apr 2008 15:06:39 +0000 (19:06 +0400)
committerLen Brown <len.brown@intel.com>
Tue, 22 Apr 2008 18:29:24 +0000 (14:29 -0400)
Fixed a problem with the Load operator when loading a table from
a buffer object. The input buffer was prematurely zeroed and/or
deleted.

http://www.acpica.org/bugzilla/show_bug.cgi?id=577

Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
Signed-off-by: Len Brown <len.brown@intel.com>
drivers/acpi/executer/exconfig.c
drivers/acpi/tables/tbinstal.c
drivers/acpi/utilities/utdebug.c

index 009aef5fcbfc6c4ed353518c1f18be3cf68d05fc..8cc410ce9208027cd4d59b5c27c271f7ac0b2dce 100644 (file)
@@ -285,16 +285,16 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
        switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
        case ACPI_TYPE_REGION:
 
+               ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Load from Region %p %s\n",
+                                 obj_desc,
+                                 acpi_ut_get_object_type_name(obj_desc)));
+
                /* Region must be system_memory (from ACPI spec) */
 
                if (obj_desc->region.space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) {
                        return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
                }
 
-               ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Load from Region %p %s\n",
-                                 obj_desc,
-                                 acpi_ut_get_object_type_name(obj_desc)));
-
                /*
                 * If the Region Address and Length have not been previously evaluated,
                 * evaluate them now and save the results.
@@ -306,6 +306,11 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
                        }
                }
 
+               /*
+                * We will simply map the memory region for the table. However, the
+                * memory region is technically not guaranteed to remain stable and
+                * we may eventually have to copy the table to a local buffer.
+                */
                table_desc.address = obj_desc->region.address;
                table_desc.length = obj_desc->region.length;
                table_desc.flags = ACPI_TABLE_ORIGIN_MAPPED;
@@ -313,18 +318,23 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
 
        case ACPI_TYPE_BUFFER:  /* Buffer or resolved region_field */
 
-               /* Simply extract the buffer from the buffer object */
-
                ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
                                  "Load from Buffer or Field %p %s\n", obj_desc,
                                  acpi_ut_get_object_type_name(obj_desc)));
 
-               table_desc.pointer = ACPI_CAST_PTR(struct acpi_table_header,
-                                                  obj_desc->buffer.pointer);
-               table_desc.length = table_desc.pointer->length;
-               table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED;
+               /*
+                * We need to copy the buffer since the original buffer could be
+                * changed or deleted in the future
+                */
+               table_desc.pointer = ACPI_ALLOCATE(obj_desc->buffer.length);
+               if (!table_desc.pointer) {
+                       return_ACPI_STATUS(AE_NO_MEMORY);
+               }
 
-               obj_desc->buffer.pointer = NULL;
+               ACPI_MEMCPY(table_desc.pointer, obj_desc->buffer.pointer,
+                           obj_desc->buffer.length);
+               table_desc.length = obj_desc->buffer.length;
+               table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED;
                break;
 
        default:
@@ -369,6 +379,9 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
 
       cleanup:
        if (ACPI_FAILURE(status)) {
+
+               /* Delete allocated buffer or mapping */
+
                acpi_tb_delete_table(&table_desc);
        }
        return_ACPI_STATUS(status);
index 3bc0c67a9283e395943ee0e42c5db83b3c43f134..6a6ee1f06c764527849310452b3bff887e84ab97 100644 (file)
@@ -125,13 +125,20 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc,
 
        /* The table must be either an SSDT or a PSDT or an OEMx */
 
-       if ((!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_PSDT))
-           &&
-           (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT))
-           && (strncmp(table_desc->pointer->signature, "OEM", 3))) {
-               ACPI_ERROR((AE_INFO,
-                           "Table has invalid signature [%4.4s], must be SSDT, PSDT or OEMx",
-                           table_desc->pointer->signature));
+       if (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_PSDT)&&
+           !ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT)&&
+           strncmp(table_desc->pointer->signature, "OEM", 3)) {
+               /* Check for a printable name */
+               if (acpi_ut_valid_acpi_name(
+                       *(u32 *) table_desc->pointer->signature)) {
+                       ACPI_ERROR((AE_INFO, "Table has invalid signature "
+                                       "[%4.4s], must be SSDT or PSDT",
+                                   table_desc->pointer->signature));
+               } else {
+                       ACPI_ERROR((AE_INFO, "Table has invalid signature "
+                                       "(0x%8.8X), must be SSDT or PSDT",
+                                   *(u32 *) table_desc->pointer->signature));
+               }
                return_ACPI_STATUS(AE_BAD_SIGNATURE);
        }
 
index 7361204b1eef2114ca22a65902dae2b6ae75276f..a9148677f037e919cd1f77a33331a1fd9a19e847 100644 (file)
@@ -524,6 +524,11 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display)
        u32 temp32;
        u8 buf_char;
 
+       if (!buffer) {
+               acpi_os_printf("Null Buffer Pointer in DumpBuffer!\n");
+               return;
+       }
+
        if ((count < 4) || (count & 0x01)) {
                display = DB_BYTE_DISPLAY;
        }