···416416 }417417 }418418419419- table_desc->validation_count++;420420- if (table_desc->validation_count == 0) {421421- table_desc->validation_count--;419419+ if (table_desc->validation_count < ACPI_MAX_TABLE_VALIDATIONS) {420420+ table_desc->validation_count++;421421+422422+ /*423423+ * Detect validation_count overflows to ensure that the warning424424+ * message will only be printed once.425425+ */426426+ if (table_desc->validation_count >= ACPI_MAX_TABLE_VALIDATIONS) {427427+ ACPI_WARNING((AE_INFO,428428+ "Table %p, Validation count overflows\n",429429+ table_desc));430430+ }422431 }423432424433 *out_table = table_desc->pointer;···454445455446 ACPI_FUNCTION_TRACE(acpi_tb_put_table);456447457457- if (table_desc->validation_count == 0) {458458- ACPI_WARNING((AE_INFO,459459- "Table %p, Validation count is zero before decrement\n",460460- table_desc));461461- return_VOID;448448+ if (table_desc->validation_count < ACPI_MAX_TABLE_VALIDATIONS) {449449+ table_desc->validation_count--;450450+451451+ /*452452+ * Detect validation_count underflows to ensure that the warning453453+ * message will only be printed once.454454+ */455455+ if (table_desc->validation_count >= ACPI_MAX_TABLE_VALIDATIONS) {456456+ ACPI_WARNING((AE_INFO,457457+ "Table %p, Validation count underflows\n",458458+ table_desc));459459+ return_VOID;460460+ }462461 }463463- table_desc->validation_count--;464462465463 if (table_desc->validation_count == 0) {466464
-9
drivers/acpi/acpica/utresrc.c
···474474 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);475475 }476476477477- /*478478- * The end_tag opcode must be followed by a zero byte.479479- * Although this byte is technically defined to be a checksum,480480- * in practice, all ASL compilers set this byte to zero.481481- */482482- if (*(aml + 1) != 0) {483483- return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);484484- }485485-486477 /* Return the pointer to the end_tag if requested */487478488479 if (!user_function) {
+14
include/acpi/actbl.h
···374374 u16 validation_count;375375};376376377377+/*378378+ * Maximum value of the validation_count field in struct acpi_table_desc.379379+ * When reached, validation_count cannot be changed any more and the table will380380+ * be permanently regarded as validated.381381+ *382382+ * This is to prevent situations in which unbalanced table get/put operations383383+ * may cause premature table unmapping in the OS to happen.384384+ *385385+ * The maximum validation count can be defined to any value, but should be386386+ * greater than the maximum number of OS early stage mapping slots to avoid387387+ * leaking early stage table mappings to the late stage.388388+ */389389+#define ACPI_MAX_TABLE_VALIDATIONS ACPI_UINT16_MAX390390+377391/* Masks for Flags field above */378392379393#define ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL (0) /* Virtual address, external maintained */