ACPICA: Add package limit checks in parser functions

Add package limit checks in parser functions to prevent out-of-bounds
access.

Link: https://github.com/acpica/acpica/commit/b31b45af2122
Signed-off-by: ikaros <void0red@gmail.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Link: https://patch.msgid.link/3212937.CbtlEUcBR6@rafael.j.wysocki
This commit is contained in:
ikaros 2026-05-27 20:09:24 +02:00 committed by Rafael J. Wysocki
parent 296eea4a36
commit d27d48a528
4 changed files with 41 additions and 0 deletions

View File

@ -512,6 +512,10 @@ acpi_status acpi_install_method(u8 *buffer)
parser_state.aml += acpi_ps_get_opcode_size(opcode);
parser_state.pkg_end = acpi_ps_get_next_package_end(&parser_state);
if ((parser_state.pkg_end > parser_state.aml_end) ||
(parser_state.pkg_end < parser_state.aml)) {
return (AE_AML_PACKAGE_LIMIT);
}
path = acpi_ps_get_next_namestring(&parser_state);
method_flags = *parser_state.aml++;

View File

@ -867,6 +867,10 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
parser_state->pkg_end =
acpi_ps_get_next_package_end(parser_state);
if ((parser_state->pkg_end > parser_state->aml_end)
|| (parser_state->pkg_end < parser_state->aml)) {
return_ACPI_STATUS(AE_AML_PACKAGE_LIMIT);
}
break;
case ARGP_FIELDLIST:

View File

@ -361,6 +361,13 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
walk_state->parser_state.aml =
acpi_ps_get_next_package_end
(&walk_state->parser_state);
if ((walk_state->parser_state.aml >
walk_state->parser_state.aml_end)
|| (walk_state->parser_state.aml <
walk_state->aml)) {
return_ACPI_STATUS
(AE_AML_PACKAGE_LIMIT);
}
walk_state->aml =
walk_state->parser_state.aml;
}
@ -421,6 +428,14 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
parser_state->aml =
acpi_ps_get_next_package_end
(parser_state);
if ((parser_state->aml >
parser_state->aml_end)
|| (parser_state->aml <
walk_state->control_state->
control.aml_predicate_start)) {
return_ACPI_STATUS
(AE_AML_PACKAGE_LIMIT);
}
walk_state->aml = parser_state->aml;
ACPI_ERROR((AE_INFO,
@ -436,6 +451,16 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
walk_state->parser_state.aml =
acpi_ps_get_next_package_end
(parser_state);
if ((walk_state->parser_state.
aml >
walk_state->parser_state.
aml_end)
|| (walk_state->
parser_state.aml <
walk_state->aml)) {
return_ACPI_STATUS
(AE_AML_PACKAGE_LIMIT);
}
walk_state->aml =
parser_state->aml;
}

View File

@ -300,6 +300,7 @@ acpi_ps_next_parse_state(struct acpi_walk_state *walk_state,
{
struct acpi_parse_state *parser_state = &walk_state->parser_state;
acpi_status status = AE_CTRL_PENDING;
u8 *aml;
ACPI_FUNCTION_TRACE_PTR(ps_next_parse_state, op);
@ -344,7 +345,14 @@ acpi_ps_next_parse_state(struct acpi_walk_state *walk_state,
* Predicate of an IF was true, and we are at the matching ELSE.
* Just close out this package
*/
aml = parser_state->aml;
parser_state->aml = acpi_ps_get_next_package_end(parser_state);
if ((parser_state->aml > parser_state->aml_end) ||
(parser_state->aml < aml)) {
status = AE_AML_PACKAGE_LIMIT;
break;
}
status = AE_CTRL_PENDING;
break;