mirror of
https://github.com/tianocore/edk2
synced 2026-08-27 00:23:19 -04:00
DynamicTablesPkg/AmiLib: Fix stack corruption in AmlCodeGenRdInterrupt
In AmlCodeGenRdInterrupt(), the IRQ list was copied directly into an EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR structure allocated on the stack. Since the structure only contains storage for the first interrupt entry, copying multiple IRQs would write beyond the allocated buffer and corrupt the stack. Fix this issue by allocating the descriptor dynamically with sufficient space to accommodate the entire IRQ list. This ensures all interrupt entries are copied safely without overwriting adjacent stack memory. Signed-off-by: Tuan Phan <tuan.phan@oss.qualcomm.com>
This commit is contained in:
parent
4d92f22a5c
commit
82dd8ab1b3
1 changed files with 22 additions and 13 deletions
|
|
@ -1266,7 +1266,8 @@ AmlCodeGenRdInterrupt (
|
|||
EFI_STATUS Status;
|
||||
|
||||
AML_DATA_NODE *RdNode;
|
||||
EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR RdInterrupt;
|
||||
EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR *RdInterrupt;
|
||||
UINT16 RdInterruptSize;
|
||||
UINT32 *FirstInterrupt;
|
||||
|
||||
if ((IrqList == NULL) ||
|
||||
|
|
@ -1277,32 +1278,40 @@ AmlCodeGenRdInterrupt (
|
|||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR already includes the first interrupt
|
||||
RdInterruptSize = sizeof (EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR) + (IrqCount - 1) * sizeof (UINT32);
|
||||
RdInterrupt = (EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR *)AllocateZeroPool (RdInterruptSize);
|
||||
if (RdInterrupt == NULL) {
|
||||
ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
// Header
|
||||
RdInterrupt.Header.Header.Bits.Name =
|
||||
RdInterrupt->Header.Header.Bits.Name =
|
||||
ACPI_LARGE_EXTENDED_IRQ_DESCRIPTOR_NAME;
|
||||
RdInterrupt.Header.Header.Bits.Type = ACPI_LARGE_ITEM_FLAG;
|
||||
RdInterrupt.Header.Length = sizeof (EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR) -
|
||||
sizeof (ACPI_LARGE_RESOURCE_HEADER);
|
||||
RdInterrupt->Header.Header.Bits.Type = ACPI_LARGE_ITEM_FLAG;
|
||||
RdInterrupt->Header.Length = RdInterruptSize - sizeof (ACPI_LARGE_RESOURCE_HEADER);
|
||||
|
||||
// Body
|
||||
RdInterrupt.InterruptVectorFlags = (ResourceConsumer ? BIT0 : 0) |
|
||||
(EdgeTriggered ? BIT1 : 0) |
|
||||
(ActiveLow ? BIT2 : 0) |
|
||||
(Shared ? BIT3 : 0);
|
||||
RdInterrupt.InterruptTableLength = IrqCount;
|
||||
RdInterrupt->InterruptVectorFlags = (ResourceConsumer ? BIT0 : 0) |
|
||||
(EdgeTriggered ? BIT1 : 0) |
|
||||
(ActiveLow ? BIT2 : 0) |
|
||||
(Shared ? BIT3 : 0);
|
||||
RdInterrupt->InterruptTableLength = IrqCount;
|
||||
|
||||
// Get the address of the first interrupt field.
|
||||
FirstInterrupt = RdInterrupt.InterruptNumber;
|
||||
FirstInterrupt = RdInterrupt->InterruptNumber;
|
||||
|
||||
// Copy the list of interrupts.
|
||||
CopyMem (FirstInterrupt, IrqList, (sizeof (UINT32) * IrqCount));
|
||||
|
||||
Status = AmlCreateDataNode (
|
||||
EAmlNodeDataTypeResourceData,
|
||||
(UINT8 *)&RdInterrupt,
|
||||
sizeof (EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR),
|
||||
(UINT8 *)RdInterrupt,
|
||||
RdInterruptSize,
|
||||
&RdNode
|
||||
);
|
||||
FreePool (RdInterrupt);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT (0);
|
||||
return Status;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue