Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5eb69180 authored by Bob Moore's avatar Bob Moore Committed by Len Brown
Browse files

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: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarAlexey Starikovskiy <astarikovskiy@suse.de>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 53cf1744
Loading
Loading
Loading
Loading
+24 −11
Original line number Original line Diff line number Diff line
@@ -285,16 +285,16 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
	case ACPI_TYPE_REGION:
	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) */
		/* Region must be system_memory (from ACPI spec) */


		if (obj_desc->region.space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) {
		if (obj_desc->region.space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) {
			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
			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,
		 * If the Region Address and Length have not been previously evaluated,
		 * evaluate them now and save the results.
		 * 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.address = obj_desc->region.address;
		table_desc.length = obj_desc->region.length;
		table_desc.length = obj_desc->region.length;
		table_desc.flags = ACPI_TABLE_ORIGIN_MAPPED;
		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 */
	case ACPI_TYPE_BUFFER:	/* Buffer or resolved region_field */


		/* Simply extract the buffer from the buffer object */

		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
				  "Load from Buffer or Field %p %s\n", obj_desc,
				  "Load from Buffer or Field %p %s\n", obj_desc,
				  acpi_ut_get_object_type_name(obj_desc)));
				  acpi_ut_get_object_type_name(obj_desc)));


		table_desc.pointer = ACPI_CAST_PTR(struct acpi_table_header,
		/*
						   obj_desc->buffer.pointer);
		 * We need to copy the buffer since the original buffer could be
		table_desc.length = table_desc.pointer->length;
		 * changed or deleted in the future
		table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED;
		 */
		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;
		break;


	default:
	default:
@@ -369,6 +379,9 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,


      cleanup:
      cleanup:
	if (ACPI_FAILURE(status)) {
	if (ACPI_FAILURE(status)) {

		/* Delete allocated buffer or mapping */

		acpi_tb_delete_table(&table_desc);
		acpi_tb_delete_table(&table_desc);
	}
	}
	return_ACPI_STATUS(status);
	return_ACPI_STATUS(status);
+14 −7
Original line number Original line Diff line number Diff line
@@ -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 */
	/* The table must be either an SSDT or a PSDT or an OEMx */


	if ((!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_PSDT))
	if (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_PSDT)&&
	    &&
	    !ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT)&&
	    (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT))
	    strncmp(table_desc->pointer->signature, "OEM", 3)) {
	    && (strncmp(table_desc->pointer->signature, "OEM", 3))) {
		/* Check for a printable name */
		ACPI_ERROR((AE_INFO,
		if (acpi_ut_valid_acpi_name(
			    "Table has invalid signature [%4.4s], must be SSDT, PSDT or OEMx",
			*(u32 *) table_desc->pointer->signature)) {
			ACPI_ERROR((AE_INFO, "Table has invalid signature "
					"[%4.4s], must be SSDT or PSDT",
				    table_desc->pointer->signature));
				    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);
		return_ACPI_STATUS(AE_BAD_SIGNATURE);
	}
	}


+5 −0
Original line number Original line Diff line number Diff line
@@ -524,6 +524,11 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display)
	u32 temp32;
	u32 temp32;
	u8 buf_char;
	u8 buf_char;


	if (!buffer) {
		acpi_os_printf("Null Buffer Pointer in DumpBuffer!\n");
		return;
	}

	if ((count < 4) || (count & 0x01)) {
	if ((count < 4) || (count & 0x01)) {
		display = DB_BYTE_DISPLAY;
		display = DB_BYTE_DISPLAY;
	}
	}