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 50 ACPI_MODULE_NAME("nsprepkg") 51 52 /* Local prototypes */ 53 static acpi_status 54 acpi_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 58 static acpi_status 59 acpi_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 80 acpi_status 81 acpi_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 372 package_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 399 static acpi_status 400 acpi_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 597 package_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 627 static acpi_status 628 acpi_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