Linux Audio

Check our new training course

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