cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

nsprepkg.c (19991B)


      1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
      2/******************************************************************************
      3 *
      4 * Module Name: nsprepkg - Validation of package objects for predefined names
      5 *
      6 * Copyright (C) 2000 - 2022, Intel Corp.
      7 *
      8 *****************************************************************************/
      9
     10#include <acpi/acpi.h>
     11#include "accommon.h"
     12#include "acnamesp.h"
     13#include "acpredef.h"
     14
     15#define _COMPONENT          ACPI_NAMESPACE
     16ACPI_MODULE_NAME("nsprepkg")
     17
     18/* Local prototypes */
     19static acpi_status
     20acpi_ns_check_package_list(struct acpi_evaluate_info *info,
     21			   const union acpi_predefined_info *package,
     22			   union acpi_operand_object **elements, u32 count);
     23
     24static acpi_status
     25acpi_ns_check_package_elements(struct acpi_evaluate_info *info,
     26			       union acpi_operand_object **elements,
     27			       u8 type1,
     28			       u32 count1,
     29			       u8 type2, u32 count2, u32 start_index);
     30
     31static acpi_status
     32acpi_ns_custom_package(struct acpi_evaluate_info *info,
     33		       union acpi_operand_object **elements, u32 count);
     34
     35/*******************************************************************************
     36 *
     37 * FUNCTION:    acpi_ns_check_package
     38 *
     39 * PARAMETERS:  info                - Method execution information block
     40 *              return_object_ptr   - Pointer to the object returned from the
     41 *                                    evaluation of a method or object
     42 *
     43 * RETURN:      Status
     44 *
     45 * DESCRIPTION: Check a returned package object for the correct count and
     46 *              correct type of all sub-objects.
     47 *
     48 ******************************************************************************/
     49
     50acpi_status
     51acpi_ns_check_package(struct acpi_evaluate_info *info,
     52		      union acpi_operand_object **return_object_ptr)
     53{
     54	union acpi_operand_object *return_object = *return_object_ptr;
     55	const union acpi_predefined_info *package;
     56	union acpi_operand_object **elements;
     57	acpi_status status = AE_OK;
     58	u32 expected_count;
     59	u32 count;
     60	u32 i;
     61
     62	ACPI_FUNCTION_TRACE(ns_check_package);
     63
     64	/* The package info for this name is in the next table entry */
     65
     66	package = info->predefined + 1;
     67
     68	ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
     69			  "%s Validating return Package of Type %X, Count %X\n",
     70			  info->full_pathname, package->ret_info.type,
     71			  return_object->package.count));
     72
     73	/*
     74	 * For variable-length Packages, we can safely remove all embedded
     75	 * and trailing NULL package elements
     76	 */
     77	acpi_ns_remove_null_elements(info, package->ret_info.type,
     78				     return_object);
     79
     80	/* Extract package count and elements array */
     81
     82	elements = return_object->package.elements;
     83	count = return_object->package.count;
     84
     85	/*
     86	 * Most packages must have at least one element. The only exception
     87	 * is the variable-length package (ACPI_PTYPE1_VAR).
     88	 */
     89	if (!count) {
     90		if (package->ret_info.type == ACPI_PTYPE1_VAR) {
     91			return_ACPI_STATUS(AE_OK);
     92		}
     93
     94		ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
     95				      info->node_flags,
     96				      "Return Package has no elements (empty)"));
     97
     98		return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
     99	}
    100
    101	/*
    102	 * Decode the type of the expected package contents
    103	 *
    104	 * PTYPE1 packages contain no subpackages
    105	 * PTYPE2 packages contain subpackages
    106	 */
    107	switch (package->ret_info.type) {
    108	case ACPI_PTYPE_CUSTOM:
    109
    110		status = acpi_ns_custom_package(info, elements, count);
    111		break;
    112
    113	case ACPI_PTYPE1_FIXED:
    114		/*
    115		 * The package count is fixed and there are no subpackages
    116		 *
    117		 * If package is too small, exit.
    118		 * If package is larger than expected, issue warning but continue
    119		 */
    120		expected_count =
    121		    package->ret_info.count1 + package->ret_info.count2;
    122		if (count < expected_count) {
    123			goto package_too_small;
    124		} else if (count > expected_count) {
    125			ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
    126					  "%s: Return Package is larger than needed - "
    127					  "found %u, expected %u\n",
    128					  info->full_pathname, count,
    129					  expected_count));
    130		}
    131
    132		/* Validate all elements of the returned package */
    133
    134		status = acpi_ns_check_package_elements(info, elements,
    135							package->ret_info.
    136							object_type1,
    137							package->ret_info.
    138							count1,
    139							package->ret_info.
    140							object_type2,
    141							package->ret_info.
    142							count2, 0);
    143		break;
    144
    145	case ACPI_PTYPE1_VAR:
    146		/*
    147		 * The package count is variable, there are no subpackages, and all
    148		 * elements must be of the same type
    149		 */
    150		for (i = 0; i < count; i++) {
    151			status = acpi_ns_check_object_type(info, elements,
    152							   package->ret_info.
    153							   object_type1, i);
    154			if (ACPI_FAILURE(status)) {
    155				return_ACPI_STATUS(status);
    156			}
    157
    158			elements++;
    159		}
    160		break;
    161
    162	case ACPI_PTYPE1_OPTION:
    163		/*
    164		 * The package count is variable, there are no subpackages. There are
    165		 * a fixed number of required elements, and a variable number of
    166		 * optional elements.
    167		 *
    168		 * Check if package is at least as large as the minimum required
    169		 */
    170		expected_count = package->ret_info3.count;
    171		if (count < expected_count) {
    172			goto package_too_small;
    173		}
    174
    175		/* Variable number of sub-objects */
    176
    177		for (i = 0; i < count; i++) {
    178			if (i < package->ret_info3.count) {
    179
    180				/* These are the required package elements (0, 1, or 2) */
    181
    182				status =
    183				    acpi_ns_check_object_type(info, elements,
    184							      package->
    185							      ret_info3.
    186							      object_type[i],
    187							      i);
    188				if (ACPI_FAILURE(status)) {
    189					return_ACPI_STATUS(status);
    190				}
    191			} else {
    192				/* These are the optional package elements */
    193
    194				status =
    195				    acpi_ns_check_object_type(info, elements,
    196							      package->
    197							      ret_info3.
    198							      tail_object_type,
    199							      i);
    200				if (ACPI_FAILURE(status)) {
    201					return_ACPI_STATUS(status);
    202				}
    203			}
    204
    205			elements++;
    206		}
    207		break;
    208
    209	case ACPI_PTYPE2_REV_FIXED:
    210
    211		/* First element is the (Integer) revision */
    212
    213		status =
    214		    acpi_ns_check_object_type(info, elements,
    215					      ACPI_RTYPE_INTEGER, 0);
    216		if (ACPI_FAILURE(status)) {
    217			return_ACPI_STATUS(status);
    218		}
    219
    220		elements++;
    221		count--;
    222
    223		/* Examine the subpackages */
    224
    225		status =
    226		    acpi_ns_check_package_list(info, package, elements, count);
    227		break;
    228
    229	case ACPI_PTYPE2_PKG_COUNT:
    230
    231		/* First element is the (Integer) count of subpackages to follow */
    232
    233		status =
    234		    acpi_ns_check_object_type(info, elements,
    235					      ACPI_RTYPE_INTEGER, 0);
    236		if (ACPI_FAILURE(status)) {
    237			return_ACPI_STATUS(status);
    238		}
    239
    240		/*
    241		 * Count cannot be larger than the parent package length, but allow it
    242		 * to be smaller. The >= accounts for the Integer above.
    243		 */
    244		expected_count = (u32)(*elements)->integer.value;
    245		if (expected_count >= count) {
    246			goto package_too_small;
    247		}
    248
    249		count = expected_count;
    250		elements++;
    251
    252		/* Examine the subpackages */
    253
    254		status =
    255		    acpi_ns_check_package_list(info, package, elements, count);
    256		break;
    257
    258	case ACPI_PTYPE2:
    259	case ACPI_PTYPE2_FIXED:
    260	case ACPI_PTYPE2_MIN:
    261	case ACPI_PTYPE2_COUNT:
    262	case ACPI_PTYPE2_FIX_VAR:
    263		/*
    264		 * These types all return a single Package that consists of a
    265		 * variable number of subpackages.
    266		 *
    267		 * First, ensure that the first element is a subpackage. If not,
    268		 * the BIOS may have incorrectly returned the object as a single
    269		 * package instead of a Package of Packages (a common error if
    270		 * there is only one entry). We may be able to repair this by
    271		 * wrapping the returned Package with a new outer Package.
    272		 */
    273		if (*elements
    274		    && ((*elements)->common.type != ACPI_TYPE_PACKAGE)) {
    275
    276			/* Create the new outer package and populate it */
    277
    278			status =
    279			    acpi_ns_wrap_with_package(info, return_object,
    280						      return_object_ptr);
    281			if (ACPI_FAILURE(status)) {
    282				return_ACPI_STATUS(status);
    283			}
    284
    285			/* Update locals to point to the new package (of 1 element) */
    286
    287			return_object = *return_object_ptr;
    288			elements = return_object->package.elements;
    289			count = 1;
    290		}
    291
    292		/* Examine the subpackages */
    293
    294		status =
    295		    acpi_ns_check_package_list(info, package, elements, count);
    296		break;
    297
    298	case ACPI_PTYPE2_VAR_VAR:
    299		/*
    300		 * Returns a variable list of packages, each with a variable list
    301		 * of objects.
    302		 */
    303		break;
    304
    305	case ACPI_PTYPE2_UUID_PAIR:
    306
    307		/* The package must contain pairs of (UUID + type) */
    308
    309		if (count & 1) {
    310			expected_count = count + 1;
    311			goto package_too_small;
    312		}
    313
    314		while (count > 0) {
    315			status = acpi_ns_check_object_type(info, elements,
    316							   package->ret_info.
    317							   object_type1, 0);
    318			if (ACPI_FAILURE(status)) {
    319				return_ACPI_STATUS(status);
    320			}
    321
    322			/* Validate length of the UUID buffer */
    323
    324			if ((*elements)->buffer.length != 16) {
    325				ACPI_WARN_PREDEFINED((AE_INFO,
    326						      info->full_pathname,
    327						      info->node_flags,
    328						      "Invalid length for UUID Buffer"));
    329				return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
    330			}
    331
    332			status = acpi_ns_check_object_type(info, elements + 1,
    333							   package->ret_info.
    334							   object_type2, 0);
    335			if (ACPI_FAILURE(status)) {
    336				return_ACPI_STATUS(status);
    337			}
    338
    339			elements += 2;
    340			count -= 2;
    341		}
    342		break;
    343
    344	default:
    345
    346		/* Should not get here if predefined info table is correct */
    347
    348		ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
    349				      info->node_flags,
    350				      "Invalid internal return type in table entry: %X",
    351				      package->ret_info.type));
    352
    353		return_ACPI_STATUS(AE_AML_INTERNAL);
    354	}
    355
    356	return_ACPI_STATUS(status);
    357
    358package_too_small:
    359
    360	/* Error exit for the case with an incorrect package count */
    361
    362	ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, info->node_flags,
    363			      "Return Package is too small - found %u elements, expected %u",
    364			      count, expected_count));
    365
    366	return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
    367}
    368
    369/*******************************************************************************
    370 *
    371 * FUNCTION:    acpi_ns_check_package_list
    372 *
    373 * PARAMETERS:  info            - Method execution information block
    374 *              package         - Pointer to package-specific info for method
    375 *              elements        - Element list of parent package. All elements
    376 *                                of this list should be of type Package.
    377 *              count           - Count of subpackages
    378 *
    379 * RETURN:      Status
    380 *
    381 * DESCRIPTION: Examine a list of subpackages
    382 *
    383 ******************************************************************************/
    384
    385static acpi_status
    386acpi_ns_check_package_list(struct acpi_evaluate_info *info,
    387			   const union acpi_predefined_info *package,
    388			   union acpi_operand_object **elements, u32 count)
    389{
    390	union acpi_operand_object *sub_package;
    391	union acpi_operand_object **sub_elements;
    392	acpi_status status;
    393	u32 expected_count;
    394	u32 i;
    395	u32 j;
    396
    397	/*
    398	 * Validate each subpackage in the parent Package
    399	 *
    400	 * NOTE: assumes list of subpackages contains no NULL elements.
    401	 * Any NULL elements should have been removed by earlier call
    402	 * to acpi_ns_remove_null_elements.
    403	 */
    404	for (i = 0; i < count; i++) {
    405		sub_package = *elements;
    406		sub_elements = sub_package->package.elements;
    407		info->parent_package = sub_package;
    408
    409		/* Each sub-object must be of type Package */
    410
    411		status = acpi_ns_check_object_type(info, &sub_package,
    412						   ACPI_RTYPE_PACKAGE, i);
    413		if (ACPI_FAILURE(status)) {
    414			return (status);
    415		}
    416
    417		/* Examine the different types of expected subpackages */
    418
    419		info->parent_package = sub_package;
    420		switch (package->ret_info.type) {
    421		case ACPI_PTYPE2:
    422		case ACPI_PTYPE2_PKG_COUNT:
    423		case ACPI_PTYPE2_REV_FIXED:
    424
    425			/* Each subpackage has a fixed number of elements */
    426
    427			expected_count =
    428			    package->ret_info.count1 + package->ret_info.count2;
    429			if (sub_package->package.count < expected_count) {
    430				goto package_too_small;
    431			}
    432
    433			status =
    434			    acpi_ns_check_package_elements(info, sub_elements,
    435							   package->ret_info.
    436							   object_type1,
    437							   package->ret_info.
    438							   count1,
    439							   package->ret_info.
    440							   object_type2,
    441							   package->ret_info.
    442							   count2, 0);
    443			if (ACPI_FAILURE(status)) {
    444				return (status);
    445			}
    446			break;
    447
    448		case ACPI_PTYPE2_FIX_VAR:
    449			/*
    450			 * Each subpackage has a fixed number of elements and an
    451			 * optional element
    452			 */
    453			expected_count =
    454			    package->ret_info.count1 + package->ret_info.count2;
    455			if (sub_package->package.count < expected_count) {
    456				goto package_too_small;
    457			}
    458
    459			status =
    460			    acpi_ns_check_package_elements(info, sub_elements,
    461							   package->ret_info.
    462							   object_type1,
    463							   package->ret_info.
    464							   count1,
    465							   package->ret_info.
    466							   object_type2,
    467							   sub_package->package.
    468							   count -
    469							   package->ret_info.
    470							   count1, 0);
    471			if (ACPI_FAILURE(status)) {
    472				return (status);
    473			}
    474			break;
    475
    476		case ACPI_PTYPE2_VAR_VAR:
    477			/*
    478			 * Each subpackage has a fixed or variable number of elements
    479			 */
    480			break;
    481
    482		case ACPI_PTYPE2_FIXED:
    483
    484			/* Each subpackage has a fixed length */
    485
    486			expected_count = package->ret_info2.count;
    487			if (sub_package->package.count < expected_count) {
    488				goto package_too_small;
    489			}
    490
    491			/* Check the type of each subpackage element */
    492
    493			for (j = 0; j < expected_count; j++) {
    494				status =
    495				    acpi_ns_check_object_type(info,
    496							      &sub_elements[j],
    497							      package->
    498							      ret_info2.
    499							      object_type[j],
    500							      j);
    501				if (ACPI_FAILURE(status)) {
    502					return (status);
    503				}
    504			}
    505			break;
    506
    507		case ACPI_PTYPE2_MIN:
    508
    509			/* Each subpackage has a variable but minimum length */
    510
    511			expected_count = package->ret_info.count1;
    512			if (sub_package->package.count < expected_count) {
    513				goto package_too_small;
    514			}
    515
    516			/* Check the type of each subpackage element */
    517
    518			status =
    519			    acpi_ns_check_package_elements(info, sub_elements,
    520							   package->ret_info.
    521							   object_type1,
    522							   sub_package->package.
    523							   count, 0, 0, 0);
    524			if (ACPI_FAILURE(status)) {
    525				return (status);
    526			}
    527			break;
    528
    529		case ACPI_PTYPE2_COUNT:
    530			/*
    531			 * First element is the (Integer) count of elements, including
    532			 * the count field (the ACPI name is num_elements)
    533			 */
    534			status = acpi_ns_check_object_type(info, sub_elements,
    535							   ACPI_RTYPE_INTEGER,
    536							   0);
    537			if (ACPI_FAILURE(status)) {
    538				return (status);
    539			}
    540
    541			/*
    542			 * Make sure package is large enough for the Count and is
    543			 * is as large as the minimum size
    544			 */
    545			expected_count = (u32)(*sub_elements)->integer.value;
    546			if (sub_package->package.count < expected_count) {
    547				goto package_too_small;
    548			}
    549
    550			if (sub_package->package.count <
    551			    package->ret_info.count1) {
    552				expected_count = package->ret_info.count1;
    553				goto package_too_small;
    554			}
    555
    556			if (expected_count == 0) {
    557				/*
    558				 * Either the num_entries element was originally zero or it was
    559				 * a NULL element and repaired to an Integer of value zero.
    560				 * In either case, repair it by setting num_entries to be the
    561				 * actual size of the subpackage.
    562				 */
    563				expected_count = sub_package->package.count;
    564				(*sub_elements)->integer.value = expected_count;
    565			}
    566
    567			/* Check the type of each subpackage element */
    568
    569			status =
    570			    acpi_ns_check_package_elements(info,
    571							   (sub_elements + 1),
    572							   package->ret_info.
    573							   object_type1,
    574							   (expected_count - 1),
    575							   0, 0, 1);
    576			if (ACPI_FAILURE(status)) {
    577				return (status);
    578			}
    579			break;
    580
    581		default:	/* Should not get here, type was validated by caller */
    582
    583			ACPI_ERROR((AE_INFO, "Invalid Package type: %X",
    584				    package->ret_info.type));
    585			return (AE_AML_INTERNAL);
    586		}
    587
    588		elements++;
    589	}
    590
    591	return (AE_OK);
    592
    593package_too_small:
    594
    595	/* The subpackage count was smaller than required */
    596
    597	ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, info->node_flags,
    598			      "Return SubPackage[%u] is too small - found %u elements, expected %u",
    599			      i, sub_package->package.count, expected_count));
    600
    601	return (AE_AML_OPERAND_VALUE);
    602}
    603
    604/*******************************************************************************
    605 *
    606 * FUNCTION:    acpi_ns_custom_package
    607 *
    608 * PARAMETERS:  info                - Method execution information block
    609 *              elements            - Pointer to the package elements array
    610 *              count               - Element count for the package
    611 *
    612 * RETURN:      Status
    613 *
    614 * DESCRIPTION: Check a returned package object for the correct count and
    615 *              correct type of all sub-objects.
    616 *
    617 * NOTE: Currently used for the _BIX method only. When needed for two or more
    618 * methods, probably a detect/dispatch mechanism will be required.
    619 *
    620 ******************************************************************************/
    621
    622static acpi_status
    623acpi_ns_custom_package(struct acpi_evaluate_info *info,
    624		       union acpi_operand_object **elements, u32 count)
    625{
    626	u32 expected_count;
    627	u32 version;
    628	acpi_status status = AE_OK;
    629
    630	ACPI_FUNCTION_NAME(ns_custom_package);
    631
    632	/* Get version number, must be Integer */
    633
    634	if ((*elements)->common.type != ACPI_TYPE_INTEGER) {
    635		ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
    636				      info->node_flags,
    637				      "Return Package has invalid object type for version number"));
    638		return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
    639	}
    640
    641	version = (u32)(*elements)->integer.value;
    642	expected_count = 21;	/* Version 1 */
    643
    644	if (version == 0) {
    645		expected_count = 20;	/* Version 0 */
    646	}
    647
    648	if (count < expected_count) {
    649		ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
    650				      info->node_flags,
    651				      "Return Package is too small - found %u elements, expected %u",
    652				      count, expected_count));
    653		return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
    654	} else if (count > expected_count) {
    655		ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
    656				  "%s: Return Package is larger than needed - "
    657				  "found %u, expected %u\n",
    658				  info->full_pathname, count, expected_count));
    659	}
    660
    661	/* Validate all elements of the returned package */
    662
    663	status = acpi_ns_check_package_elements(info, elements,
    664						ACPI_RTYPE_INTEGER, 16,
    665						ACPI_RTYPE_STRING, 4, 0);
    666	if (ACPI_FAILURE(status)) {
    667		return_ACPI_STATUS(status);
    668	}
    669
    670	/* Version 1 has a single trailing integer */
    671
    672	if (version > 0) {
    673		status = acpi_ns_check_package_elements(info, elements + 20,
    674							ACPI_RTYPE_INTEGER, 1,
    675							0, 0, 20);
    676	}
    677
    678	return_ACPI_STATUS(status);
    679}
    680
    681/*******************************************************************************
    682 *
    683 * FUNCTION:    acpi_ns_check_package_elements
    684 *
    685 * PARAMETERS:  info            - Method execution information block
    686 *              elements        - Pointer to the package elements array
    687 *              type1           - Object type for first group
    688 *              count1          - Count for first group
    689 *              type2           - Object type for second group
    690 *              count2          - Count for second group
    691 *              start_index     - Start of the first group of elements
    692 *
    693 * RETURN:      Status
    694 *
    695 * DESCRIPTION: Check that all elements of a package are of the correct object
    696 *              type. Supports up to two groups of different object types.
    697 *
    698 ******************************************************************************/
    699
    700static acpi_status
    701acpi_ns_check_package_elements(struct acpi_evaluate_info *info,
    702			       union acpi_operand_object **elements,
    703			       u8 type1,
    704			       u32 count1,
    705			       u8 type2, u32 count2, u32 start_index)
    706{
    707	union acpi_operand_object **this_element = elements;
    708	acpi_status status;
    709	u32 i;
    710
    711	ACPI_FUNCTION_TRACE(ns_check_package_elements);
    712
    713	/*
    714	 * Up to two groups of package elements are supported by the data
    715	 * structure. All elements in each group must be of the same type.
    716	 * The second group can have a count of zero.
    717	 */
    718	for (i = 0; i < count1; i++) {
    719		status = acpi_ns_check_object_type(info, this_element,
    720						   type1, i + start_index);
    721		if (ACPI_FAILURE(status)) {
    722			return_ACPI_STATUS(status);
    723		}
    724
    725		this_element++;
    726	}
    727
    728	for (i = 0; i < count2; i++) {
    729		status = acpi_ns_check_object_type(info, this_element,
    730						   type2,
    731						   (i + count1 + start_index));
    732		if (ACPI_FAILURE(status)) {
    733			return_ACPI_STATUS(status);
    734		}
    735
    736		this_element++;
    737	}
    738
    739	return_ACPI_STATUS(AE_OK);
    740}