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_predefined_data *data, 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_predefined_data *data, 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: data - Pointer to validation data structure 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_predefined_data *data, 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 = data->predefined + 1; 97 98 ACPI_DEBUG_PRINT((ACPI_DB_NAMES, 99 "%s Validating return Package of Type %X, Count %X\n", 100 data->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(data, 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, data->pathname, data->node_flags, 125 "Return Package has no elements (empty)")); 126 127 return (AE_AML_OPERAND_VALUE); 128 } 129 130 /* 131 * Decode the type of the expected package contents 132 * 133 * PTYPE1 packages contain no subpackages 134 * PTYPE2 packages contain sub-packages 135 */ 136 switch (package->ret_info.type) { 137 case ACPI_PTYPE1_FIXED: 138 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 data->pathname, count, 154 expected_count)); 155 } 156 157 /* Validate all elements of the returned package */ 158 159 status = acpi_ns_check_package_elements(data, 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 /* 173 * The package count is variable, there are no sub-packages, and all 174 * elements must be of the same type 175 */ 176 for (i = 0; i < count; i++) { 177 status = acpi_ns_check_object_type(data, elements, 178 package->ret_info. 179 object_type1, i); 180 if (ACPI_FAILURE(status)) { 181 return (status); 182 } 183 elements++; 184 } 185 break; 186 187 case ACPI_PTYPE1_OPTION: 188 189 /* 190 * The package count is variable, there are no sub-packages. There are 191 * a fixed number of required elements, and a variable number of 192 * optional elements. 193 * 194 * Check if package is at least as large as the minimum required 195 */ 196 expected_count = package->ret_info3.count; 197 if (count < expected_count) { 198 goto package_too_small; 199 } 200 201 /* Variable number of sub-objects */ 202 203 for (i = 0; i < count; i++) { 204 if (i < package->ret_info3.count) { 205 206 /* These are the required package elements (0, 1, or 2) */ 207 208 status = 209 acpi_ns_check_object_type(data, elements, 210 package-> 211 ret_info3. 212 object_type[i], 213 i); 214 if (ACPI_FAILURE(status)) { 215 return (status); 216 } 217 } else { 218 /* These are the optional package elements */ 219 220 status = 221 acpi_ns_check_object_type(data, elements, 222 package-> 223 ret_info3. 224 tail_object_type, 225 i); 226 if (ACPI_FAILURE(status)) { 227 return (status); 228 } 229 } 230 elements++; 231 } 232 break; 233 234 case ACPI_PTYPE2_REV_FIXED: 235 236 /* First element is the (Integer) revision */ 237 238 status = acpi_ns_check_object_type(data, elements, 239 ACPI_RTYPE_INTEGER, 0); 240 if (ACPI_FAILURE(status)) { 241 return (status); 242 } 243 244 elements++; 245 count--; 246 247 /* Examine the sub-packages */ 248 249 status = 250 acpi_ns_check_package_list(data, package, elements, count); 251 break; 252 253 case ACPI_PTYPE2_PKG_COUNT: 254 255 /* First element is the (Integer) count of sub-packages to follow */ 256 257 status = acpi_ns_check_object_type(data, 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 sub-packages */ 276 277 status = 278 acpi_ns_check_package_list(data, 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 /* 288 * These types all return a single Package that consists of a 289 * variable number of sub-Packages. 290 * 291 * First, ensure that the first element is a sub-Package. If not, 292 * the BIOS may have incorrectly returned the object as a single 293 * package instead of a Package of Packages (a common error if 294 * there is only one entry). We may be able to repair this by 295 * wrapping the returned Package with a new outer Package. 296 */ 297 if (*elements 298 && ((*elements)->common.type != ACPI_TYPE_PACKAGE)) { 299 300 /* Create the new outer package and populate it */ 301 302 status = 303 acpi_ns_wrap_with_package(data, return_object, 304 return_object_ptr); 305 if (ACPI_FAILURE(status)) { 306 return (status); 307 } 308 309 /* Update locals to point to the new package (of 1 element) */ 310 311 return_object = *return_object_ptr; 312 elements = return_object->package.elements; 313 count = 1; 314 } 315 316 /* Examine the sub-packages */ 317 318 status = 319 acpi_ns_check_package_list(data, package, elements, count); 320 break; 321 322 default: 323 324 /* Should not get here if predefined info table is correct */ 325 326 ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, 327 "Invalid internal return type in table entry: %X", 328 package->ret_info.type)); 329 330 return (AE_AML_INTERNAL); 331 } 332 333 return (status); 334 335 package_too_small: 336 337 /* Error exit for the case with an incorrect package count */ 338 339 ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, 340 "Return Package is too small - found %u elements, expected %u", 341 count, expected_count)); 342 343 return (AE_AML_OPERAND_VALUE); 344 } 345 346 /******************************************************************************* 347 * 348 * FUNCTION: acpi_ns_check_package_list 349 * 350 * PARAMETERS: data - Pointer to validation data structure 351 * package - Pointer to package-specific info for method 352 * elements - Element list of parent package. All elements 353 * of this list should be of type Package. 354 * count - Count of subpackages 355 * 356 * RETURN: Status 357 * 358 * DESCRIPTION: Examine a list of subpackages 359 * 360 ******************************************************************************/ 361 362 static acpi_status 363 acpi_ns_check_package_list(struct acpi_predefined_data *data, 364 const union acpi_predefined_info *package, 365 union acpi_operand_object **elements, u32 count) 366 { 367 union acpi_operand_object *sub_package; 368 union acpi_operand_object **sub_elements; 369 acpi_status status; 370 u32 expected_count; 371 u32 i; 372 u32 j; 373 374 /* 375 * Validate each sub-Package in the parent Package 376 * 377 * NOTE: assumes list of sub-packages contains no NULL elements. 378 * Any NULL elements should have been removed by earlier call 379 * to acpi_ns_remove_null_elements. 380 */ 381 for (i = 0; i < count; i++) { 382 sub_package = *elements; 383 sub_elements = sub_package->package.elements; 384 data->parent_package = sub_package; 385 386 /* Each sub-object must be of type Package */ 387 388 status = acpi_ns_check_object_type(data, &sub_package, 389 ACPI_RTYPE_PACKAGE, i); 390 if (ACPI_FAILURE(status)) { 391 return (status); 392 } 393 394 /* Examine the different types of expected sub-packages */ 395 396 data->parent_package = sub_package; 397 switch (package->ret_info.type) { 398 case ACPI_PTYPE2: 399 case ACPI_PTYPE2_PKG_COUNT: 400 case ACPI_PTYPE2_REV_FIXED: 401 402 /* Each subpackage has a fixed number of elements */ 403 404 expected_count = 405 package->ret_info.count1 + package->ret_info.count2; 406 if (sub_package->package.count < expected_count) { 407 goto package_too_small; 408 } 409 410 status = 411 acpi_ns_check_package_elements(data, sub_elements, 412 package->ret_info. 413 object_type1, 414 package->ret_info. 415 count1, 416 package->ret_info. 417 object_type2, 418 package->ret_info. 419 count2, 0); 420 if (ACPI_FAILURE(status)) { 421 return (status); 422 } 423 break; 424 425 case ACPI_PTYPE2_FIX_VAR: 426 /* 427 * Each subpackage has a fixed number of elements and an 428 * optional element 429 */ 430 expected_count = 431 package->ret_info.count1 + package->ret_info.count2; 432 if (sub_package->package.count < expected_count) { 433 goto package_too_small; 434 } 435 436 status = 437 acpi_ns_check_package_elements(data, sub_elements, 438 package->ret_info. 439 object_type1, 440 package->ret_info. 441 count1, 442 package->ret_info. 443 object_type2, 444 sub_package->package. 445 count - 446 package->ret_info. 447 count1, 0); 448 if (ACPI_FAILURE(status)) { 449 return (status); 450 } 451 break; 452 453 case ACPI_PTYPE2_FIXED: 454 455 /* Each sub-package has a fixed length */ 456 457 expected_count = package->ret_info2.count; 458 if (sub_package->package.count < expected_count) { 459 goto package_too_small; 460 } 461 462 /* Check the type of each sub-package element */ 463 464 for (j = 0; j < expected_count; j++) { 465 status = 466 acpi_ns_check_object_type(data, 467 &sub_elements[j], 468 package-> 469 ret_info2. 470 object_type[j], 471 j); 472 if (ACPI_FAILURE(status)) { 473 return (status); 474 } 475 } 476 break; 477 478 case ACPI_PTYPE2_MIN: 479 480 /* Each sub-package has a variable but minimum length */ 481 482 expected_count = package->ret_info.count1; 483 if (sub_package->package.count < expected_count) { 484 goto package_too_small; 485 } 486 487 /* Check the type of each sub-package element */ 488 489 status = 490 acpi_ns_check_package_elements(data, sub_elements, 491 package->ret_info. 492 object_type1, 493 sub_package->package. 494 count, 0, 0, 0); 495 if (ACPI_FAILURE(status)) { 496 return (status); 497 } 498 break; 499 500 case ACPI_PTYPE2_COUNT: 501 502 /* 503 * First element is the (Integer) count of elements, including 504 * the count field (the ACPI name is num_elements) 505 */ 506 status = acpi_ns_check_object_type(data, sub_elements, 507 ACPI_RTYPE_INTEGER, 508 0); 509 if (ACPI_FAILURE(status)) { 510 return (status); 511 } 512 513 /* 514 * Make sure package is large enough for the Count and is 515 * is as large as the minimum size 516 */ 517 expected_count = (u32)(*sub_elements)->integer.value; 518 if (sub_package->package.count < expected_count) { 519 goto package_too_small; 520 } 521 if (sub_package->package.count < 522 package->ret_info.count1) { 523 expected_count = package->ret_info.count1; 524 goto package_too_small; 525 } 526 if (expected_count == 0) { 527 /* 528 * Either the num_entries element was originally zero or it was 529 * a NULL element and repaired to an Integer of value zero. 530 * In either case, repair it by setting num_entries to be the 531 * actual size of the subpackage. 532 */ 533 expected_count = sub_package->package.count; 534 (*sub_elements)->integer.value = expected_count; 535 } 536 537 /* Check the type of each sub-package element */ 538 539 status = 540 acpi_ns_check_package_elements(data, 541 (sub_elements + 1), 542 package->ret_info. 543 object_type1, 544 (expected_count - 1), 545 0, 0, 1); 546 if (ACPI_FAILURE(status)) { 547 return (status); 548 } 549 break; 550 551 default: /* Should not get here, type was validated by caller */ 552 553 return (AE_AML_INTERNAL); 554 } 555 556 elements++; 557 } 558 559 return (AE_OK); 560 561 package_too_small: 562 563 /* The sub-package count was smaller than required */ 564 565 ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, 566 "Return Sub-Package[%u] is too small - found %u elements, expected %u", 567 i, sub_package->package.count, expected_count)); 568 569 return (AE_AML_OPERAND_VALUE); 570 } 571 572 /******************************************************************************* 573 * 574 * FUNCTION: acpi_ns_check_package_elements 575 * 576 * PARAMETERS: data - Pointer to validation data structure 577 * elements - Pointer to the package elements array 578 * type1 - Object type for first group 579 * count1 - Count for first group 580 * type2 - Object type for second group 581 * count2 - Count for second group 582 * start_index - Start of the first group of elements 583 * 584 * RETURN: Status 585 * 586 * DESCRIPTION: Check that all elements of a package are of the correct object 587 * type. Supports up to two groups of different object types. 588 * 589 ******************************************************************************/ 590 591 static acpi_status 592 acpi_ns_check_package_elements(struct acpi_predefined_data *data, 593 union acpi_operand_object **elements, 594 u8 type1, 595 u32 count1, 596 u8 type2, u32 count2, u32 start_index) 597 { 598 union acpi_operand_object **this_element = elements; 599 acpi_status status; 600 u32 i; 601 602 /* 603 * Up to two groups of package elements are supported by the data 604 * structure. All elements in each group must be of the same type. 605 * The second group can have a count of zero. 606 */ 607 for (i = 0; i < count1; i++) { 608 status = acpi_ns_check_object_type(data, this_element, 609 type1, i + start_index); 610 if (ACPI_FAILURE(status)) { 611 return (status); 612 } 613 this_element++; 614 } 615 616 for (i = 0; i < count2; i++) { 617 status = acpi_ns_check_object_type(data, this_element, 618 type2, 619 (i + count1 + start_index)); 620 if (ACPI_FAILURE(status)) { 621 return (status); 622 } 623 this_element++; 624 } 625 626 return (AE_OK); 627 } 628