summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorikaros <void0red@gmail.com>2026-05-27 21:09:24 +0300
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2026-05-27 21:18:47 +0300
commitd27d48a528e437aed690f977e69a6fe73fe82ab5 (patch)
tree1f1285f5f899c1e2e31d93bdf8167d1e93cd3d1d
parent296eea4a364d59df5e4ca45c2ff26600cbef293b (diff)
downloadlinux-d27d48a528e437aed690f977e69a6fe73fe82ab5.tar.xz
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
-rw-r--r--drivers/acpi/acpica/nsxfname.c4
-rw-r--r--drivers/acpi/acpica/psargs.c4
-rw-r--r--drivers/acpi/acpica/psloop.c25
-rw-r--r--drivers/acpi/acpica/psparse.c8
4 files changed, 41 insertions, 0 deletions
diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c
index fabae9b08e31..b6534187cd43 100644
--- a/drivers/acpi/acpica/nsxfname.c
+++ b/drivers/acpi/acpica/nsxfname.c
@@ -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++;
diff --git a/drivers/acpi/acpica/psargs.c b/drivers/acpi/acpica/psargs.c
index cafd54fb5868..95d540bda4fb 100644
--- a/drivers/acpi/acpica/psargs.c
+++ b/drivers/acpi/acpica/psargs.c
@@ -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:
diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c
index e012495e2267..24a57f971c96 100644
--- a/drivers/acpi/acpica/psloop.c
+++ b/drivers/acpi/acpica/psloop.c
@@ -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;
}
diff --git a/drivers/acpi/acpica/psparse.c b/drivers/acpi/acpica/psparse.c
index d9e4f33b6909..29b57d2c4cc4 100644
--- a/drivers/acpi/acpica/psparse.c
+++ b/drivers/acpi/acpica/psparse.c
@@ -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;