diff options
Diffstat (limited to 'source/components/parser/psargs.c')
| -rw-r--r-- | source/components/parser/psargs.c | 136 |
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++; |
