1 /****************************************************************************** 2 * 3 * Module Name: nsprepkg - Validation of package objects for predefined names 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2013, 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 sub-packages 136 */ 137 switch (package->ret_info.type) { 138 case ACPI_PTYPE1_FIXED: 139 /* 140 * The package count is fixed and there are no sub-packages 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 sub-packages, 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 sub-packages. 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 sub-packages */ 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 sub-packages 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 sub-packages */ 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 sub-Packages. 287 * 288 * First, ensure that the first element is a sub-Package. 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 sub-packages */ 314 315 status = 316 acpi_ns_check_package_list(info, package, elements, count); 317 break; 318 319 default: 320 321 /* Should not get here if predefined info table is correct */ 322 323 ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, 324 info->node_flags, 325 "Invalid internal return type in table entry: %X", 326 package->ret_info.type)); 327 328 return (AE_AML_INTERNAL); 329 } 330 331 return (status); 332 333 package_too_small: 334 335 /* Error exit for the case with an incorrect package count */ 336 337 ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, info->node_flags, 338 "Return Package is too small - found %u elements, expected %u", 339 count, expected_count)); 340 341 return (AE_AML_OPERAND_VALUE); 342 } 343 344 /******************************************************************************* 345 * 346 * FUNCTION: acpi_ns_check_package_list 347 * 348 * PARAMETERS: info - Method execution information block 349 * package - Pointer to package-specific info for method 350 * elements - Element list of parent package. All elements 351 * of this list should be of type Package. 352 * count - Count of subpackages 353 * 354 * RETURN: Status 355 * 356 * DESCRIPTION: Examine a list of subpackages 357 * 358 ******************************************************************************/ 359 360 static acpi_status 361 acpi_ns_check_package_list(struct acpi_evaluate_info *info, 362 const union acpi_predefined_info *package, 363 union acpi_operand_object **elements, u32 count) 364 { 365 union acpi_operand_object *sub_package; 366 union acpi_operand_object **sub_elements; 367 acpi_status status; 368 u32 expected_count; 369 u32 i; 370 u32 j; 371 372 /* 373 * Validate each sub-Package in the parent Package 374 * 375 * NOTE: assumes list of sub-packages contains no NULL elements. 376 * Any NULL elements should have been removed by earlier call 377 * to acpi_ns_remove_null_elements. 378 */ 379 for (i = 0; i < count; i++) { 380 sub_package = *elements; 381 sub_elements = sub_package->package.elements; 382 info->parent_package = sub_package; 383 384 /* Each sub-object must be of type Package */ 385 386 status = acpi_ns_check_object_type(info, &sub_package, 387 ACPI_RTYPE_PACKAGE, i); 388 if (ACPI_FAILURE(status)) { 389 return (status); 390 } 391 392 /* Examine the different types of expected sub-packages */ 393 394 info->parent_package = sub_package; 395 switch (package->ret_info.type) { 396 case ACPI_PTYPE2: 397 case ACPI_PTYPE2_PKG_COUNT: 398 case ACPI_PTYPE2_REV_FIXED: 399 400 /* Each subpackage has a fixed number of elements */ 401 402 expected_count = 403 package->ret_info.count1 + package->ret_info.count2; 404 if (sub_package->package.count < expected_count) { 405 goto package_too_small; 406 } 407 408 status = 409 acpi_ns_check_package_elements(info, sub_elements, 410 package->ret_info. 411 object_type1, 412 package->ret_info. 413 count1, 414 package->ret_info. 415 object_type2, 416 package->ret_info. 417 count2, 0); 418 if (ACPI_FAILURE(status)) { 419 return (status); 420 } 421 break; 422 423 case ACPI_PTYPE2_FIX_VAR: 424 /* 425 * Each subpackage has a fixed number of elements and an 426 * optional element 427 */ 428 expected_count = 429 package->ret_info.count1 + package->ret_info.count2; 430 if (sub_package->package.count < expected_count) { 431 goto package_too_small; 432 } 433 434 status = 435 acpi_ns_check_package_elements(info, sub_elements, 436 package->ret_info. 437 object_type1, 438 package->ret_info. 439 count1, 440 package->ret_info. 441 object_type2, 442 sub_package->package. 443 count - 444 package->ret_info. 445 count1, 0); 446 if (ACPI_FAILURE(status)) { 447 return (status); 448 } 449 break; 450 451 case ACPI_PTYPE2_FIXED: 452 453 /* Each sub-package has a fixed length */ 454 455 expected_count = package->ret_info2.count; 456 if (sub_package->package.count < expected_count) { 457 goto package_too_small; 458 } 459 460 /* Check the type of each sub-package element */ 461 462 for (j = 0; j < expected_count; j++) { 463 status = 464 acpi_ns_check_object_type(info, 465 &sub_elements[j], 466 package-> 467 ret_info2. 468 object_type[j], 469 j); 470 if (ACPI_FAILURE(status)) { 471 return (status); 472 } 473 } 474 break; 475 476 case ACPI_PTYPE2_MIN: 477 478 /* Each sub-package has a variable but minimum length */ 479 480 expected_count = package->ret_info.count1; 481 if (sub_package->package.count < expected_count) { 482 goto package_too_small; 483 } 484 485 /* Check the type of each sub-package element */ 486 487 status = 488 acpi_ns_check_package_elements(info, sub_elements, 489 package->ret_info. 490 object_type1, 491 sub_package->package. 492 count, 0, 0, 0); 493 if (ACPI_FAILURE(status)) { 494 return (status); 495 } 496 break; 497 498 case ACPI_PTYPE2_COUNT: 499 /* 500 * First element is the (Integer) count of elements, including 501 * the count field (the ACPI name is num_elements) 502 */ 503 status = acpi_ns_check_object_type(info, sub_elements, 504 ACPI_RTYPE_INTEGER, 505 0); 506 if (ACPI_FAILURE(status)) { 507 return (status); 508 } 509 510 /* 511 * Make sure package is large enough for the Count and is 512 * is as large as the minimum size 513 */ 514 expected_count = (u32)(*sub_elements)->integer.value; 515 if (sub_package->package.count < expected_count) { 516 goto package_too_small; 517 } 518 if (sub_package->package.count < 519 package->ret_info.count1) { 520 expected_count = package->ret_info.count1; 521 goto package_too_small; 522 } 523 if (expected_count == 0) { 524 /* 525 * Either the num_entries element was originally zero or it was 526 * a NULL element and repaired to an Integer of value zero. 527 * In either case, repair it by setting num_entries to be the 528 * actual size of the subpackage. 529 */ 530 expected_count = sub_package->package.count; 531 (*sub_elements)->integer.value = expected_count; 532 } 533 534 /* Check the type of each sub-package element */ 535 536 status = 537 acpi_ns_check_package_elements(info, 538 (sub_elements + 1), 539 package->ret_info. 540 object_type1, 541 (expected_count - 1), 542 0, 0, 1); 543 if (ACPI_FAILURE(status)) { 544 return (status); 545 } 546 break; 547 548 default: /* Should not get here, type was validated by caller */ 549 550 return (AE_AML_INTERNAL); 551 } 552 553 elements++; 554 } 555 556 return (AE_OK); 557 558 package_too_small: 559 560 /* The sub-package count was smaller than required */ 561 562 ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, info->node_flags, 563 "Return Sub-Package[%u] is too small - found %u elements, expected %u", 564 i, sub_package->package.count, expected_count)); 565 566 return (AE_AML_OPERAND_VALUE); 567 } 568 569 /******************************************************************************* 570 * 571 * FUNCTION: acpi_ns_check_package_elements 572 * 573 * PARAMETERS: info - Method execution information block 574 * elements - Pointer to the package elements array 575 * type1 - Object type for first group 576 * count1 - Count for first group 577 * type2 - Object type for second group 578 * count2 - Count for second group 579 * start_index - Start of the first group of elements 580 * 581 * RETURN: Status 582 * 583 * DESCRIPTION: Check that all elements of a package are of the correct object 584 * type. Supports up to two groups of different object types. 585 * 586 ******************************************************************************/ 587 588 static acpi_status 589 acpi_ns_check_package_elements(struct acpi_evaluate_info *info, 590 union acpi_operand_object **elements, 591 u8 type1, 592 u32 count1, 593 u8 type2, u32 count2, u32 start_index) 594 { 595 union acpi_operand_object **this_element = elements; 596 acpi_status status; 597 u32 i; 598 599 /* 600 * Up to two groups of package elements are supported by the data 601 * structure. All elements in each group must be of the same type. 602 * The second group can have a count of zero. 603 */ 604 for (i = 0; i < count1; i++) { 605 status = acpi_ns_check_object_type(info, this_element, 606 type1, i + start_index); 607 if (ACPI_FAILURE(status)) { 608 return (status); 609 } 610 this_element++; 611 } 612 613 for (i = 0; i < count2; i++) { 614 status = acpi_ns_check_object_type(info, this_element, 615 type2, 616 (i + count1 + start_index)); 617 if (ACPI_FAILURE(status)) { 618 return (status); 619 } 620 this_element++; 621 } 622 623 return (AE_OK); 624 } 625