aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2008-04-10 11:06:39 -0400
committerLen Brown <len.brown@intel.com>2008-04-22 14:29:24 -0400
commit5eb691805f7ec5960fe9d5d7fc57a7fc3097bbd0 (patch)
treebd968bd9717f55a32ff9a30062aad025854c3bc6
parent53cf174409a24e8388e1d554d27436275fc81fe7 (diff)
ACPICA: Fix for fault if Load() fails
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>
-rw-r--r--drivers/acpi/executer/exconfig.c35
-rw-r--r--drivers/acpi/tables/tbinstal.c21
-rw-r--r--drivers/acpi/utilities/utdebug.c5
3 files changed, 43 insertions, 18 deletions
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c
index 009aef5fcbfc..8cc410ce9208 100644
--- a/drivers/acpi/executer/exconfig.c
+++ b/drivers/acpi/executer/exconfig.c
@@ -285,16 +285,16 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
285 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { 285 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
286 case ACPI_TYPE_REGION: 286 case ACPI_TYPE_REGION:
287 287
288 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Load from Region %p %s\n",
289 obj_desc,
290 acpi_ut_get_object_type_name(obj_desc)));
291
288 /* Region must be system_memory (from ACPI spec) */ 292 /* Region must be system_memory (from ACPI spec) */
289 293
290 if (obj_desc->region.space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) { 294 if (obj_desc->region.space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) {
291 return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 295 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
292 } 296 }
293 297
294 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Load from Region %p %s\n",
295 obj_desc,
296 acpi_ut_get_object_type_name(obj_desc)));
297
298 /* 298 /*
299 * If the Region Address and Length have not been previously evaluated, 299 * If the Region Address and Length have not been previously evaluated,
300 * evaluate them now and save the results. 300 * evaluate them now and save the results.
@@ -306,6 +306,11 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
306 } 306 }
307 } 307 }
308 308
309 /*
310 * We will simply map the memory region for the table. However, the
311 * memory region is technically not guaranteed to remain stable and
312 * we may eventually have to copy the table to a local buffer.
313 */
309 table_desc.address = obj_desc->region.address; 314 table_desc.address = obj_desc->region.address;
310 table_desc.length = obj_desc->region.length; 315 table_desc.length = obj_desc->region.length;
311 table_desc.flags = ACPI_TABLE_ORIGIN_MAPPED; 316 table_desc.flags = ACPI_TABLE_ORIGIN_MAPPED;
@@ -313,18 +318,23 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
313 318
314 case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */ 319 case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */
315 320
316 /* Simply extract the buffer from the buffer object */
317
318 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 321 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
319 "Load from Buffer or Field %p %s\n", obj_desc, 322 "Load from Buffer or Field %p %s\n", obj_desc,
320 acpi_ut_get_object_type_name(obj_desc))); 323 acpi_ut_get_object_type_name(obj_desc)));
321 324
322 table_desc.pointer = ACPI_CAST_PTR(struct acpi_table_header, 325 /*
323 obj_desc->buffer.pointer); 326 * We need to copy the buffer since the original buffer could be
324 table_desc.length = table_desc.pointer->length; 327 * changed or deleted in the future
325 table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED; 328 */
329 table_desc.pointer = ACPI_ALLOCATE(obj_desc->buffer.length);
330 if (!table_desc.pointer) {
331 return_ACPI_STATUS(AE_NO_MEMORY);
332 }
326 333
327 obj_desc->buffer.pointer = NULL; 334 ACPI_MEMCPY(table_desc.pointer, obj_desc->buffer.pointer,
335 obj_desc->buffer.length);
336 table_desc.length = obj_desc->buffer.length;
337 table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED;
328 break; 338 break;
329 339
330 default: 340 default:
@@ -369,6 +379,9 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
369 379
370 cleanup: 380 cleanup:
371 if (ACPI_FAILURE(status)) { 381 if (ACPI_FAILURE(status)) {
382
383 /* Delete allocated buffer or mapping */
384
372 acpi_tb_delete_table(&table_desc); 385 acpi_tb_delete_table(&table_desc);
373 } 386 }
374 return_ACPI_STATUS(status); 387 return_ACPI_STATUS(status);
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c
index 3bc0c67a9283..6a6ee1f06c76 100644
--- a/drivers/acpi/tables/tbinstal.c
+++ b/drivers/acpi/tables/tbinstal.c
@@ -125,13 +125,20 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc,
125 125
126 /* The table must be either an SSDT or a PSDT or an OEMx */ 126 /* The table must be either an SSDT or a PSDT or an OEMx */
127 127
128 if ((!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_PSDT)) 128 if (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_PSDT)&&
129 && 129 !ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT)&&
130 (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT)) 130 strncmp(table_desc->pointer->signature, "OEM", 3)) {
131 && (strncmp(table_desc->pointer->signature, "OEM", 3))) { 131 /* Check for a printable name */
132 ACPI_ERROR((AE_INFO, 132 if (acpi_ut_valid_acpi_name(
133 "Table has invalid signature [%4.4s], must be SSDT, PSDT or OEMx", 133 *(u32 *) table_desc->pointer->signature)) {
134 table_desc->pointer->signature)); 134 ACPI_ERROR((AE_INFO, "Table has invalid signature "
135 "[%4.4s], must be SSDT or PSDT",
136 table_desc->pointer->signature));
137 } else {
138 ACPI_ERROR((AE_INFO, "Table has invalid signature "
139 "(0x%8.8X), must be SSDT or PSDT",
140 *(u32 *) table_desc->pointer->signature));
141 }
135 return_ACPI_STATUS(AE_BAD_SIGNATURE); 142 return_ACPI_STATUS(AE_BAD_SIGNATURE);
136 } 143 }
137 144
diff --git a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/utilities/utdebug.c
index 7361204b1eef..a9148677f037 100644
--- a/drivers/acpi/utilities/utdebug.c
+++ b/drivers/acpi/utilities/utdebug.c
@@ -524,6 +524,11 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display)
524 u32 temp32; 524 u32 temp32;
525 u8 buf_char; 525 u8 buf_char;
526 526
527 if (!buffer) {
528 acpi_os_printf("Null Buffer Pointer in DumpBuffer!\n");
529 return;
530 }
531
527 if ((count < 4) || (count & 0x01)) { 532 if ((count < 4) || (count & 0x01)) {
528 display = DB_BYTE_DISPLAY; 533 display = DB_BYTE_DISPLAY;
529 } 534 }