summaryrefslogtreecommitdiff
path: root/source/components/parser/psargs.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/components/parser/psargs.c')
-rw-r--r--source/components/parser/psargs.c136
1 files changed, 125 insertions, 11 deletions
diff --git a/source/components/parser/psargs.c b/source/components/parser/psargs.c
index 36afbd73bad4..e9dadf4a40ad 100644
--- a/source/components/parser/psargs.c
+++ b/source/components/parser/psargs.c
@@ -8,7 +8,7 @@
*
* 1. Copyright Notice
*
- * Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.
+ * Some or all of this work - Copyright (c) 1999 - 2026, Intel Corp.
* All rights reserved.
*
* 2. License
@@ -197,6 +197,7 @@ AcpiPsGetNextPackageLength (
UINT32 PackageLength = 0;
UINT32 ByteCount;
UINT8 ByteZeroMask = 0x3F; /* Default [0:5] */
+ UINT32 Remaining;
ACPI_FUNCTION_TRACE (PsGetNextPackageLength);
@@ -206,7 +207,24 @@ AcpiPsGetNextPackageLength (
* Byte 0 bits [6:7] contain the number of additional bytes
* used to encode the package length, either 0,1,2, or 3
*/
+
+ /* Check if we have at least one byte to read */
+ Remaining = (UINT32) ACPI_PTR_DIFF (ParserState->AmlEnd, Aml);
+ if (Remaining == 0)
+ {
+ return_UINT32 (0);
+ }
+
ByteCount = (Aml[0] >> 6);
+
+ /* Validate ByteCount and ensure we have enough bytes to read */
+ if (ByteCount >= Remaining)
+ {
+ /* Clamp to available bytes and advance to end */
+ ParserState->Aml = ParserState->AmlEnd;
+ return_UINT32 (0);
+ }
+
ParserState->Aml += ((ACPI_SIZE) ByteCount + 1);
/* Get bytes 3, 2, 1 as needed */
@@ -545,6 +563,8 @@ AcpiPsGetNextSimpleArg (
UINT32 Length;
UINT16 Opcode;
UINT8 *Aml = ParserState->Aml;
+ UINT32 Remaining = (UINT32) ACPI_PTR_DIFF (ParserState->AmlEnd, Aml);
+ UINT64 PartialValue;
ACPI_FUNCTION_TRACE_U32 (PsGetNextSimpleArg, ArgType);
@@ -557,8 +577,16 @@ AcpiPsGetNextSimpleArg (
/* Get 1 byte from the AML stream */
Opcode = AML_BYTE_OP;
- Arg->Common.Value.Integer = (UINT64) *Aml;
- Length = 1;
+ if (Remaining >= 1)
+ {
+ Arg->Common.Value.Integer = (UINT64) *Aml;
+ Length = 1;
+ }
+ else
+ {
+ Arg->Common.Value.Integer = 0;
+ Length = 0;
+ }
break;
case ARGP_WORDDATA:
@@ -566,8 +594,23 @@ AcpiPsGetNextSimpleArg (
/* Get 2 bytes from the AML stream */
Opcode = AML_WORD_OP;
- ACPI_MOVE_16_TO_64 (&Arg->Common.Value.Integer, Aml);
- Length = 2;
+ if (Remaining >= 2)
+ {
+ ACPI_MOVE_16_TO_64 (&Arg->Common.Value.Integer, Aml);
+ Length = 2;
+ }
+ else
+ {
+ Arg->Common.Value.Integer = 0;
+ Length = 0;
+ if (Remaining > 0)
+ {
+ PartialValue = 0;
+ memcpy (&PartialValue, Aml, Remaining);
+ Arg->Common.Value.Integer = PartialValue;
+ Length = Remaining;
+ }
+ }
break;
case ARGP_DWORDDATA:
@@ -575,8 +618,23 @@ AcpiPsGetNextSimpleArg (
/* Get 4 bytes from the AML stream */
Opcode = AML_DWORD_OP;
- ACPI_MOVE_32_TO_64 (&Arg->Common.Value.Integer, Aml);
- Length = 4;
+ if (Remaining >= 4)
+ {
+ ACPI_MOVE_32_TO_64 (&Arg->Common.Value.Integer, Aml);
+ Length = 4;
+ }
+ else
+ {
+ Arg->Common.Value.Integer = 0;
+ Length = 0;
+ if (Remaining > 0)
+ {
+ PartialValue = 0;
+ memcpy (&PartialValue, Aml, Remaining);
+ Arg->Common.Value.Integer = PartialValue;
+ Length = Remaining;
+ }
+ }
break;
case ARGP_QWORDDATA:
@@ -584,8 +642,23 @@ AcpiPsGetNextSimpleArg (
/* Get 8 bytes from the AML stream */
Opcode = AML_QWORD_OP;
- ACPI_MOVE_64_TO_64 (&Arg->Common.Value.Integer, Aml);
- Length = 8;
+ if (Remaining >= 8)
+ {
+ ACPI_MOVE_64_TO_64 (&Arg->Common.Value.Integer, Aml);
+ Length = 8;
+ }
+ else
+ {
+ Arg->Common.Value.Integer = 0;
+ Length = 0;
+ if (Remaining > 0)
+ {
+ PartialValue = 0;
+ memcpy (&PartialValue, Aml, Remaining);
+ Arg->Common.Value.Integer = PartialValue;
+ Length = Remaining;
+ }
+ }
break;
case ARGP_CHARLIST:
@@ -598,11 +671,32 @@ AcpiPsGetNextSimpleArg (
/* Find the null terminator */
Length = 0;
- while (Aml[Length])
+ while ((Length < Remaining) && Aml[Length])
+ {
+ Length++;
+ }
+ if (Length < Remaining)
{
+ /* Account for the terminating null */
Length++;
}
- Length++;
+ else
+ {
+ /*
+ * No terminator found - add null at buffer boundary
+ * and report a warning
+ */
+ ACPI_WARNING ((AE_INFO,
+ "Invalid AML string: no null terminator, truncating at offset %u",
+ (UINT32) (Aml - ParserState->Aml)));
+
+ /* Add null terminator at the boundary */
+ if (Remaining > 0)
+ {
+ Aml[Remaining - 1] = 0;
+ Length = Remaining;
+ }
+ }
break;
case ARGP_NAME:
@@ -659,6 +753,11 @@ AcpiPsGetNextField (
ASL_CV_CAPTURE_COMMENTS_ONLY (ParserState);
Aml = ParserState->Aml;
+ if (Aml >= ParserState->AmlEnd)
+ {
+ return_PTR (NULL);
+ }
+
/* Determine field type */
switch (ACPI_GET8 (ParserState->Aml))
@@ -710,6 +809,11 @@ AcpiPsGetNextField (
/* Get the 4-character name */
+ if ((ParserState->Aml + ACPI_NAMESEG_SIZE) > ParserState->AmlEnd)
+ {
+ AcpiPsFreeOp (Field);
+ return_PTR (NULL);
+ }
ACPI_MOVE_32_TO_32 (&Name, ParserState->Aml);
AcpiPsSetName (Field, Name);
ParserState->Aml += ACPI_NAMESEG_SIZE;
@@ -756,6 +860,11 @@ AcpiPsGetNextField (
/* Get the two bytes (Type/Attribute) */
+ if ((ParserState->Aml + 2) > ParserState->AmlEnd)
+ {
+ AcpiPsFreeOp (Field);
+ return_PTR (NULL);
+ }
AccessType = ACPI_GET8 (ParserState->Aml);
ParserState->Aml++;
AccessAttribute = ACPI_GET8 (ParserState->Aml);
@@ -768,6 +877,11 @@ AcpiPsGetNextField (
if (Opcode == AML_INT_EXTACCESSFIELD_OP)
{
+ if (ParserState->Aml >= ParserState->AmlEnd)
+ {
+ AcpiPsFreeOp (Field);
+ return_PTR (NULL);
+ }
AccessLength = ACPI_GET8 (ParserState->Aml);
ParserState->Aml++;