summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornjl <njl@FreeBSD.org>2003-09-19 19:08:55 +0000
committernjl <njl@FreeBSD.org>2003-09-19 19:08:55 +0000
commit45d0402d172b73d9028c888c37e08cbea5da870c (patch)
treeda4a0a807e8d028f38f4f4d444bf8332f696888f
parent8ee2083a45d902f399603bc6df52aef0dc32fccb (diff)
downloadFreeBSD-src-45d0402d172b73d9028c888c37e08cbea5da870c.zip
FreeBSD-src-45d0402d172b73d9028c888c37e08cbea5da870c.tar.gz
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 <ler@lerctr.org> PR: kern/56254
-rw-r--r--sys/contrib/dev/acpica/rsaddr.c40
-rw-r--r--sys/contrib/dev/acpica/rsirq.c13
2 files changed, 42 insertions, 11 deletions
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 */
OpenPOWER on IntegriCloud