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

ACPICA: Do not abort table load on invalid space ID

Ignore an invalid space ID during a table load. Instead, detect it
if a control method attempts access - then abort the method.

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



Signed-off-by: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarLin Ming <ming.m.lin@intel.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 46dfb09c
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -468,6 +468,8 @@ void acpi_ex_eisa_id_to_string(char *dest, u64 compressed_id);

void acpi_ex_integer_to_string(char *dest, u64 value);

u8 acpi_is_valid_space_id(u8 space_id);

/*
 * exregion - default op_region handlers
 */
+13 −10
Original line number Diff line number Diff line
@@ -267,7 +267,7 @@ acpi_status acpi_ex_create_mutex(struct acpi_walk_state *walk_state)
 *
 * PARAMETERS:  aml_start           - Pointer to the region declaration AML
 *              aml_length          - Max length of the declaration AML
 *              region_space        - space_iD for the region
 *              space_id            - Address space ID for the region
 *              walk_state          - Current state
 *
 * RETURN:      Status
@@ -279,7 +279,7 @@ acpi_status acpi_ex_create_mutex(struct acpi_walk_state *walk_state)
acpi_status
acpi_ex_create_region(u8 * aml_start,
		      u32 aml_length,
		      u8 region_space, struct acpi_walk_state *walk_state)
		      u8 space_id, struct acpi_walk_state *walk_state)
{
	acpi_status status;
	union acpi_operand_object *obj_desc;
@@ -304,16 +304,19 @@ acpi_ex_create_region(u8 * aml_start,
	 * Space ID must be one of the predefined IDs, or in the user-defined
	 * range
	 */
	if ((region_space >= ACPI_NUM_PREDEFINED_REGIONS) &&
	    (region_space < ACPI_USER_REGION_BEGIN) &&
	    (region_space != ACPI_ADR_SPACE_DATA_TABLE)) {
		ACPI_ERROR((AE_INFO, "Invalid AddressSpace type 0x%X",
			    region_space));
		return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID);
	if (!acpi_is_valid_space_id(space_id)) {
		/*
		 * Print an error message, but continue. We don't want to abort
		 * a table load for this exception. Instead, if the region is
		 * actually used at runtime, abort the executing method.
		 */
		ACPI_ERROR((AE_INFO,
			    "Invalid/unknown Address Space ID: 0x%2.2X",
			    space_id));
	}

	ACPI_DEBUG_PRINT((ACPI_DB_LOAD, "Region Type - %s (0x%X)\n",
			  acpi_ut_get_region_name(region_space), region_space));
			  acpi_ut_get_region_name(space_id), space_id));

	/* Create the region descriptor */

@@ -339,7 +342,7 @@ acpi_ex_create_region(u8 * aml_start,

	/* Init the region from the operands */

	obj_desc->region.space_id = region_space;
	obj_desc->region.space_id = space_id;
	obj_desc->region.address = 0;
	obj_desc->region.length = 0;
	obj_desc->region.node = node;
+14 −2
Original line number Diff line number Diff line
@@ -86,6 +86,7 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc,
{
	acpi_status status = AE_OK;
	union acpi_operand_object *rgn_desc;
	u8 space_id;

	ACPI_FUNCTION_TRACE_U32(ex_setup_region, field_datum_byte_offset);

@@ -101,6 +102,17 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc,
		return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
	}

	space_id = rgn_desc->region.space_id;

	/* Validate the Space ID */

	if (!acpi_is_valid_space_id(space_id)) {
		ACPI_ERROR((AE_INFO,
			    "Invalid/unknown Address Space ID: 0x%2.2X",
			    space_id));
		return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID);
	}

	/*
	 * If the Region Address and Length have not been previously evaluated,
	 * evaluate them now and save the results.
@@ -122,8 +134,8 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc,
	 * Exit now for SMBus or IPMI address space, it has a non-linear
	 * address space and the request cannot be directly validated
	 */
	if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS ||
	    rgn_desc->region.space_id == ACPI_ADR_SPACE_IPMI) {
	if (space_id == ACPI_ADR_SPACE_SMBUS ||
	    space_id == ACPI_ADR_SPACE_IPMI) {

		/* SMBus or IPMI has a non-linear address space */

+25 −0
Original line number Diff line number Diff line
@@ -435,4 +435,29 @@ void acpi_ex_integer_to_string(char *out_string, u64 value)
	}
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_is_valid_space_id
 *
 * PARAMETERS:  space_id            - ID to be validated
 *
 * RETURN:      TRUE if valid/supported ID.
 *
 * DESCRIPTION: Validate an operation region space_iD.
 *
 ******************************************************************************/

u8 acpi_is_valid_space_id(u8 space_id)
{

	if ((space_id >= ACPI_NUM_PREDEFINED_REGIONS) &&
	    (space_id < ACPI_USER_REGION_BEGIN) &&
	    (space_id != ACPI_ADR_SPACE_DATA_TABLE) &&
	    (space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) {
		return (FALSE);
	}

	return (TRUE);
}

#endif