1/******************************************************************************
2 *
3 * Module Name: nsprepkg - Validation of package objects for predefined names
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2014, 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 = acpi_ns_check_object_type(info, elements,
237						   ACPI_RTYPE_INTEGER, 0);
238		if (ACPI_FAILURE(status)) {
239			return (status);
240		}
241
242		elements++;
243		count--;
244
245		/* Examine the subpackages */
246
247		status =
248		    acpi_ns_check_package_list(info, package, elements, count);
249		break;
250
251	case ACPI_PTYPE2_PKG_COUNT:
252
253		/* First element is the (Integer) count of subpackages to follow */
254
255		status = acpi_ns_check_object_type(info, elements,
256						   ACPI_RTYPE_INTEGER, 0);
257		if (ACPI_FAILURE(status)) {
258			return (status);
259		}
260
261		/*
262		 * Count cannot be larger than the parent package length, but allow it
263		 * to be smaller. The >= accounts for the Integer above.
264		 */
265		expected_count = (u32)(*elements)->integer.value;
266		if (expected_count >= count) {
267			goto package_too_small;
268		}
269
270		count = expected_count;
271		elements++;
272
273		/* Examine the subpackages */
274
275		status =
276		    acpi_ns_check_package_list(info, package, elements, count);
277		break;
278
279	case ACPI_PTYPE2:
280	case ACPI_PTYPE2_FIXED:
281	case ACPI_PTYPE2_MIN:
282	case ACPI_PTYPE2_COUNT:
283	case ACPI_PTYPE2_FIX_VAR:
284		/*
285		 * These types all return a single Package that consists of a
286		 * variable number of subpackages.
287		 *
288		 * First, ensure that the first element is a subpackage. If not,
289		 * the BIOS may have incorrectly returned the object as a single
290		 * package instead of a Package of Packages (a common error if
291		 * there is only one entry). We may be able to repair this by
292		 * wrapping the returned Package with a new outer Package.
293		 */
294		if (*elements
295		    && ((*elements)->common.type != ACPI_TYPE_PACKAGE)) {
296
297			/* Create the new outer package and populate it */
298
299			status =
300			    acpi_ns_wrap_with_package(info, return_object,
301						      return_object_ptr);
302			if (ACPI_FAILURE(status)) {
303				return (status);
304			}
305
306			/* Update locals to point to the new package (of 1 element) */
307
308			return_object = *return_object_ptr;
309			elements = return_object->package.elements;
310			count = 1;
311		}
312
313		/* Examine the subpackages */
314
315		status =
316		    acpi_ns_check_package_list(info, package, elements, count);
317		break;
318
319	case ACPI_PTYPE2_UUID_PAIR:
320
321		/* The package must contain pairs of (UUID + type) */
322
323		if (count & 1) {
324			expected_count = count + 1;
325			goto package_too_small;
326		}
327
328		while (count > 0) {
329			status = acpi_ns_check_object_type(info, elements,
330							   package->ret_info.
331							   object_type1, 0);
332			if (ACPI_FAILURE(status)) {
333				return (status);
334			}
335
336			/* Validate length of the UUID buffer */
337
338			if ((*elements)->buffer.length != 16) {
339				ACPI_WARN_PREDEFINED((AE_INFO,
340						      info->full_pathname,
341						      info->node_flags,
342						      "Invalid length for UUID Buffer"));
343				return (AE_AML_OPERAND_VALUE);
344			}
345
346			status = acpi_ns_check_object_type(info, elements + 1,
347							   package->ret_info.
348							   object_type2, 0);
349			if (ACPI_FAILURE(status)) {
350				return (status);
351			}
352
353			elements += 2;
354			count -= 2;
355		}
356		break;
357
358	default:
359
360		/* Should not get here if predefined info table is correct */
361
362		ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
363				      info->node_flags,
364				      "Invalid internal return type in table entry: %X",
365				      package->ret_info.type));
366
367		return (AE_AML_INTERNAL);
368	}
369
370	return (status);
371
372package_too_small:
373
374	/* Error exit for the case with an incorrect package count */
375
376	ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, info->node_flags,
377			      "Return Package is too small - found %u elements, expected %u",
378			      count, expected_count));
379
380	return (AE_AML_OPERAND_VALUE);
381}
382
383/*******************************************************************************
384 *
385 * FUNCTION:    acpi_ns_check_package_list
386 *
387 * PARAMETERS:  info            - Method execution information block
388 *              package         - Pointer to package-specific info for method
389 *              elements        - Element list of parent package. All elements
390 *                                of this list should be of type Package.
391 *              count           - Count of subpackages
392 *
393 * RETURN:      Status
394 *
395 * DESCRIPTION: Examine a list of subpackages
396 *
397 ******************************************************************************/
398
399static acpi_status
400acpi_ns_check_package_list(struct acpi_evaluate_info *info,
401			   const union acpi_predefined_info *package,
402			   union acpi_operand_object **elements, u32 count)
403{
404	union acpi_operand_object *sub_package;
405	union acpi_operand_object **sub_elements;
406	acpi_status status;
407	u32 expected_count;
408	u32 i;
409	u32 j;
410
411	/*
412	 * Validate each subpackage in the parent Package
413	 *
414	 * NOTE: assumes list of subpackages contains no NULL elements.
415	 * Any NULL elements should have been removed by earlier call
416	 * to acpi_ns_remove_null_elements.
417	 */
418	for (i = 0; i < count; i++) {
419		sub_package = *elements;
420		sub_elements = sub_package->package.elements;
421		info->parent_package = sub_package;
422
423		/* Each sub-object must be of type Package */
424
425		status = acpi_ns_check_object_type(info, &sub_package,
426						   ACPI_RTYPE_PACKAGE, i);
427		if (ACPI_FAILURE(status)) {
428			return (status);
429		}
430
431		/* Examine the different types of expected subpackages */
432
433		info->parent_package = sub_package;
434		switch (package->ret_info.type) {
435		case ACPI_PTYPE2:
436		case ACPI_PTYPE2_PKG_COUNT:
437		case ACPI_PTYPE2_REV_FIXED:
438
439			/* Each subpackage has a fixed number of elements */
440
441			expected_count =
442			    package->ret_info.count1 + package->ret_info.count2;
443			if (sub_package->package.count < expected_count) {
444				goto package_too_small;
445			}
446
447			status =
448			    acpi_ns_check_package_elements(info, sub_elements,
449							   package->ret_info.
450							   object_type1,
451							   package->ret_info.
452							   count1,
453							   package->ret_info.
454							   object_type2,
455							   package->ret_info.
456							   count2, 0);
457			if (ACPI_FAILURE(status)) {
458				return (status);
459			}
460			break;
461
462		case ACPI_PTYPE2_FIX_VAR:
463			/*
464			 * Each subpackage has a fixed number of elements and an
465			 * optional element
466			 */
467			expected_count =
468			    package->ret_info.count1 + package->ret_info.count2;
469			if (sub_package->package.count < expected_count) {
470				goto package_too_small;
471			}
472
473			status =
474			    acpi_ns_check_package_elements(info, sub_elements,
475							   package->ret_info.
476							   object_type1,
477							   package->ret_info.
478							   count1,
479							   package->ret_info.
480							   object_type2,
481							   sub_package->package.
482							   count -
483							   package->ret_info.
484							   count1, 0);
485			if (ACPI_FAILURE(status)) {
486				return (status);
487			}
488			break;
489
490		case ACPI_PTYPE2_FIXED:
491
492			/* Each subpackage has a fixed length */
493
494			expected_count = package->ret_info2.count;
495			if (sub_package->package.count < expected_count) {
496				goto package_too_small;
497			}
498
499			/* Check the type of each subpackage element */
500
501			for (j = 0; j < expected_count; j++) {
502				status =
503				    acpi_ns_check_object_type(info,
504							      &sub_elements[j],
505							      package->
506							      ret_info2.
507							      object_type[j],
508							      j);
509				if (ACPI_FAILURE(status)) {
510					return (status);
511				}
512			}
513			break;
514
515		case ACPI_PTYPE2_MIN:
516
517			/* Each subpackage has a variable but minimum length */
518
519			expected_count = package->ret_info.count1;
520			if (sub_package->package.count < expected_count) {
521				goto package_too_small;
522			}
523
524			/* Check the type of each subpackage element */
525
526			status =
527			    acpi_ns_check_package_elements(info, sub_elements,
528							   package->ret_info.
529							   object_type1,
530							   sub_package->package.
531							   count, 0, 0, 0);
532			if (ACPI_FAILURE(status)) {
533				return (status);
534			}
535			break;
536
537		case ACPI_PTYPE2_COUNT:
538			/*
539			 * First element is the (Integer) count of elements, including
540			 * the count field (the ACPI name is num_elements)
541			 */
542			status = acpi_ns_check_object_type(info, sub_elements,
543							   ACPI_RTYPE_INTEGER,
544							   0);
545			if (ACPI_FAILURE(status)) {
546				return (status);
547			}
548
549			/*
550			 * Make sure package is large enough for the Count and is
551			 * is as large as the minimum size
552			 */
553			expected_count = (u32)(*sub_elements)->integer.value;
554			if (sub_package->package.count < expected_count) {
555				goto package_too_small;
556			}
557			if (sub_package->package.count <
558			    package->ret_info.count1) {
559				expected_count = package->ret_info.count1;
560				goto package_too_small;
561			}
562			if (expected_count == 0) {
563				/*
564				 * Either the num_entries element was originally zero or it was
565				 * a NULL element and repaired to an Integer of value zero.
566				 * In either case, repair it by setting num_entries to be the
567				 * actual size of the subpackage.
568				 */
569				expected_count = sub_package->package.count;
570				(*sub_elements)->integer.value = expected_count;
571			}
572
573			/* Check the type of each subpackage element */
574
575			status =
576			    acpi_ns_check_package_elements(info,
577							   (sub_elements + 1),
578							   package->ret_info.
579							   object_type1,
580							   (expected_count - 1),
581							   0, 0, 1);
582			if (ACPI_FAILURE(status)) {
583				return (status);
584			}
585			break;
586
587		default:	/* Should not get here, type was validated by caller */
588
589			return (AE_AML_INTERNAL);
590		}
591
592		elements++;
593	}
594
595	return (AE_OK);
596
597package_too_small:
598
599	/* The subpackage count was smaller than required */
600
601	ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, info->node_flags,
602			      "Return SubPackage[%u] is too small - found %u elements, expected %u",
603			      i, sub_package->package.count, expected_count));
604
605	return (AE_AML_OPERAND_VALUE);
606}
607
608/*******************************************************************************
609 *
610 * FUNCTION:    acpi_ns_check_package_elements
611 *
612 * PARAMETERS:  info            - Method execution information block
613 *              elements        - Pointer to the package elements array
614 *              type1           - Object type for first group
615 *              count1          - Count for first group
616 *              type2           - Object type for second group
617 *              count2          - Count for second group
618 *              start_index     - Start of the first group of elements
619 *
620 * RETURN:      Status
621 *
622 * DESCRIPTION: Check that all elements of a package are of the correct object
623 *              type. Supports up to two groups of different object types.
624 *
625 ******************************************************************************/
626
627static acpi_status
628acpi_ns_check_package_elements(struct acpi_evaluate_info *info,
629			       union acpi_operand_object **elements,
630			       u8 type1,
631			       u32 count1,
632			       u8 type2, u32 count2, u32 start_index)
633{
634	union acpi_operand_object **this_element = elements;
635	acpi_status status;
636	u32 i;
637
638	/*
639	 * Up to two groups of package elements are supported by the data
640	 * structure. All elements in each group must be of the same type.
641	 * The second group can have a count of zero.
642	 */
643	for (i = 0; i < count1; i++) {
644		status = acpi_ns_check_object_type(info, this_element,
645						   type1, i + start_index);
646		if (ACPI_FAILURE(status)) {
647			return (status);
648		}
649		this_element++;
650	}
651
652	for (i = 0; i < count2; i++) {
653		status = acpi_ns_check_object_type(info, this_element,
654						   type2,
655						   (i + count1 + start_index));
656		if (ACPI_FAILURE(status)) {
657			return (status);
658		}
659		this_element++;
660	}
661
662	return (AE_OK);
663}
664