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