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