Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'acpica-fixes'

* acpica-fixes:
ACPICA: Tables: Mechanism to handle late stage acpi_get_table() imbalance
Revert "ACPICA: Disassembler: Enhance resource descriptor detection"

+39 -18
+25 -9
drivers/acpi/acpica/tbutils.c
··· 416 416 } 417 417 } 418 418 419 - table_desc->validation_count++; 420 - if (table_desc->validation_count == 0) { 421 - table_desc->validation_count--; 419 + if (table_desc->validation_count < ACPI_MAX_TABLE_VALIDATIONS) { 420 + table_desc->validation_count++; 421 + 422 + /* 423 + * Detect validation_count overflows to ensure that the warning 424 + * message will only be printed once. 425 + */ 426 + if (table_desc->validation_count >= ACPI_MAX_TABLE_VALIDATIONS) { 427 + ACPI_WARNING((AE_INFO, 428 + "Table %p, Validation count overflows\n", 429 + table_desc)); 430 + } 422 431 } 423 432 424 433 *out_table = table_desc->pointer; ··· 454 445 455 446 ACPI_FUNCTION_TRACE(acpi_tb_put_table); 456 447 457 - if (table_desc->validation_count == 0) { 458 - ACPI_WARNING((AE_INFO, 459 - "Table %p, Validation count is zero before decrement\n", 460 - table_desc)); 461 - return_VOID; 448 + if (table_desc->validation_count < ACPI_MAX_TABLE_VALIDATIONS) { 449 + table_desc->validation_count--; 450 + 451 + /* 452 + * Detect validation_count underflows to ensure that the warning 453 + * message will only be printed once. 454 + */ 455 + if (table_desc->validation_count >= ACPI_MAX_TABLE_VALIDATIONS) { 456 + ACPI_WARNING((AE_INFO, 457 + "Table %p, Validation count underflows\n", 458 + table_desc)); 459 + return_VOID; 460 + } 462 461 } 463 - table_desc->validation_count--; 464 462 465 463 if (table_desc->validation_count == 0) { 466 464
-9
drivers/acpi/acpica/utresrc.c
··· 474 474 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); 475 475 } 476 476 477 - /* 478 - * The end_tag opcode must be followed by a zero byte. 479 - * Although this byte is technically defined to be a checksum, 480 - * in practice, all ASL compilers set this byte to zero. 481 - */ 482 - if (*(aml + 1) != 0) { 483 - return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); 484 - } 485 - 486 477 /* Return the pointer to the end_tag if requested */ 487 478 488 479 if (!user_function) {
+14
include/acpi/actbl.h
··· 374 374 u16 validation_count; 375 375 }; 376 376 377 + /* 378 + * Maximum value of the validation_count field in struct acpi_table_desc. 379 + * When reached, validation_count cannot be changed any more and the table will 380 + * be permanently regarded as validated. 381 + * 382 + * This is to prevent situations in which unbalanced table get/put operations 383 + * may cause premature table unmapping in the OS to happen. 384 + * 385 + * The maximum validation count can be defined to any value, but should be 386 + * greater than the maximum number of OS early stage mapping slots to avoid 387 + * leaking early stage table mappings to the late stage. 388 + */ 389 + #define ACPI_MAX_TABLE_VALIDATIONS ACPI_UINT16_MAX 390 + 377 391 /* Masks for Flags field above */ 378 392 379 393 #define ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL (0) /* Virtual address, external maintained */