From 45d0402d172b73d9028c888c37e08cbea5da870c Mon Sep 17 00:00:00 2001 From: njl Date: Fri, 19 Sep 2003 19:08:55 +0000 Subject: Fix an overflow in the resource list code for Address16, 32, 64, and extended irq lists. If the resource has a trailing byte but not the full resource string, do not attempt to parse the resource string. This fixes panics on transition to battery and shutdown for Larry. Patch has been submitted to vendor and they will incorporate in next release. Tested by: Larry Rosenman PR: kern/56254 --- sys/contrib/dev/acpica/rsaddr.c | 40 ++++++++++++++++++++++++++++++---------- sys/contrib/dev/acpica/rsirq.c | 13 ++++++++++++- 2 files changed, 42 insertions(+), 11 deletions(-) (limited to 'sys/contrib') diff --git a/sys/contrib/dev/acpica/rsaddr.c b/sys/contrib/dev/acpica/rsaddr.c index fe083cb..8f3eceb 100644 --- a/sys/contrib/dev/acpica/rsaddr.c +++ b/sys/contrib/dev/acpica/rsaddr.c @@ -168,6 +168,10 @@ AcpiRsAddress16Resource ( Buffer += 1; ACPI_MOVE_16_TO_16 (&Temp16, Buffer); + /* Check for the minimum length. */ + if (Temp16 < 13) + return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); + *BytesConsumed = Temp16 + 3; OutputStruct->Id = ACPI_RSTYPE_ADDRESS16; @@ -275,11 +279,13 @@ AcpiRsAddress16Resource ( /* * This will leave us pointing to the Resource Source Index * If it is present, then save it off and calculate the - * pointer to where the null terminated string goes: - * Each Interrupt takes 32-bits + the 5 bytes of the - * stream that are default. + * pointer to where the null terminated string goes. + * + * Note that some buggy resources have a length that indicates the + * Index byte is present even though it isn't (since there is no + * following Resource String.) We add one to catch these. */ - if (*BytesConsumed > 16) + if (*BytesConsumed > 16 + 1) { /* Dereference the Index */ @@ -555,6 +561,10 @@ AcpiRsAddress32Resource ( */ Buffer += 1; ACPI_MOVE_16_TO_16 (&Temp16, Buffer); + + /* Check for the minimum length. */ + if (Temp16 < 23) + return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); *BytesConsumed = Temp16 + 3; OutputStruct->Id = ACPI_RSTYPE_ADDRESS32; @@ -667,9 +677,13 @@ AcpiRsAddress32Resource ( /* * This will leave us pointing to the Resource Source Index * If it is present, then save it off and calculate the - * pointer to where the null terminated string goes: + * pointer to where the null terminated string goes. + * + * Note that some buggy resources have a length that indicates the + * Index byte is present even though it isn't (since there is no + * following Resource String.) We add one to catch these. */ - if (*BytesConsumed > 26) + if (*BytesConsumed > 26 + 1) { /* Dereference the Index */ @@ -944,7 +958,11 @@ AcpiRsAddress64Resource ( Buffer += 1; ACPI_MOVE_16_TO_16 (&Temp16, Buffer); + /* Check for the minimum length. */ + if (Temp16 < 43) + return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); *BytesConsumed = Temp16 + 3; + OutputStruct->Id = ACPI_RSTYPE_ADDRESS64; /* @@ -1056,11 +1074,13 @@ AcpiRsAddress64Resource ( /* * This will leave us pointing to the Resource Source Index * If it is present, then save it off and calculate the - * pointer to where the null terminated string goes: - * Each Interrupt takes 32-bits + the 5 bytes of the - * stream that are default. + * pointer to where the null terminated string goes. + * + * Note that some buggy resources have a length that indicates the + * Index byte is present even though it isn't (since there is no + * following Resource String.) We add one to catch these. */ - if (*BytesConsumed > 46) + if (*BytesConsumed > 46 + 1) { /* Dereference the Index */ diff --git a/sys/contrib/dev/acpica/rsirq.c b/sys/contrib/dev/acpica/rsirq.c index a8d5c16..e0e1c38 100644 --- a/sys/contrib/dev/acpica/rsirq.c +++ b/sys/contrib/dev/acpica/rsirq.c @@ -408,7 +408,11 @@ AcpiRsExtendedIrqResource ( Buffer += 1; ACPI_MOVE_16_TO_16 (&Temp16, Buffer); + /* Check for the minimum length. */ + if (Temp16 < 6) + return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); *BytesConsumed = Temp16 + 3; + OutputStruct->Id = ACPI_RSTYPE_EXT_IRQ; /* @@ -446,6 +450,12 @@ AcpiRsExtendedIrqResource ( Buffer += 1; Temp8 = *Buffer; + /* Minimum number of IRQs is one. */ + if (Temp8 < 1) { + *BytesConsumed = 0; + return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE); + } + OutputStruct->Data.ExtendedIrq.NumberOfInterrupts = Temp8; /* @@ -480,7 +490,8 @@ AcpiRsExtendedIrqResource ( * stream that are default. */ if (*BytesConsumed > - ((ACPI_SIZE) OutputStruct->Data.ExtendedIrq.NumberOfInterrupts * 4) + 5) + ((ACPI_SIZE) OutputStruct->Data.ExtendedIrq.NumberOfInterrupts * 4) + + 5 + 1) { /* Dereference the Index */ -- cgit v1.1