From 7b5a01c90b240d126efc86f9f99100db918d452e Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 18 Nov 2022 09:48:08 -0800 Subject: [PATCH 1/4] Introduce ACPI_FLEX_ARRAY Add helper to work around the pointless C99 requirement that flex array members not be allowed in unions (nor alone in structs), which is not actually a real-world problem. --- source/include/platform/acenv.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/source/include/platform/acenv.h b/source/include/platform/acenv.h index 674c4c7d02..1cae95fd66 100644 --- a/source/include/platform/acenv.h +++ b/source/include/platform/acenv.h @@ -418,6 +418,17 @@ #define ACPI_STRUCT_INIT(field, value) value #endif +/* + * Flexible array members are not allowed to be part of a union under + * C99, but this is not for any technical reason. Work around the + * limitation. + */ +#define ACPI_FLEX_ARRAY(TYPE, NAME) \ + struct { \ + struct { } __Empty_ ## NAME; \ + TYPE NAME[]; \ + } + /* * Configurable calling conventions: * From cc3a0ab278d23a6b880d001fb14e4f33ba299fc5 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 18 Nov 2022 09:49:35 -0800 Subject: [PATCH 2/4] ACPI_MADT_OEM_DATA: Fix flexible array member definition Use ACPI_FLEX_ARRAY() helper to define flexible array member alone in a struct. Fixes issue #812. --- source/include/actbl2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/include/actbl2.h b/source/include/actbl2.h index 10c61f8e23..2faea8e41a 100644 --- a/source/include/actbl2.h +++ b/source/include/actbl2.h @@ -1550,7 +1550,7 @@ enum AcpiMadtLpcPicVersion { typedef struct acpi_madt_oem_data { - UINT8 OemData[]; + ACPI_FLEX_ARRAY(UINT8, OemData); } ACPI_MADT_OEM_DATA; From 8a8443112b4ab0bc8897daa9470fc84591538b05 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Thu, 17 Nov 2022 20:48:16 -0800 Subject: [PATCH 3/4] ACPI_RESOURCE_EXTENDED_IRQ: Replace 1-element array with flexible array Similar to commit 7ba2f3d91a32 ("Replace one-element array with flexible-array"), replace the 1-element array with a proper flexible array member as defined by C99. This allows the code to operate without tripping compile-time and run-time bounds checkers (e.g. via __builtin_object_size(), -fsanitize=bounds, and/or -fstrict-flex-arrays=3). --- source/include/acrestyp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/include/acrestyp.h b/source/include/acrestyp.h index f045c2000b..1df0624268 100644 --- a/source/include/acrestyp.h +++ b/source/include/acrestyp.h @@ -538,7 +538,7 @@ typedef struct acpi_resource_extended_irq UINT8 WakeCapable; UINT8 InterruptCount; ACPI_RESOURCE_SOURCE ResourceSource; - UINT32 Interrupts[1]; + UINT32 Interrupts[]; } ACPI_RESOURCE_EXTENDED_IRQ; From b1c7901e102cec378d08643d88683ff9536a69bc Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Thu, 17 Nov 2022 20:42:06 -0800 Subject: [PATCH 4/4] ACPI_PCI_ROUTING_TABLE: Replace fixed-size array with flex array member The "Source" array is actually a dynamically sized array, but it is defined as a fixed-size 4 byte array. This results in tripping both compile-time and run-time bounds checkers (e.g. via either __builtin_object_size() or -fsanitize=bounds). To retain the padding, create a union with an unused Pad variable of size 4, and redefine Source as a proper flexible array member. --- source/include/acrestyp.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/include/acrestyp.h b/source/include/acrestyp.h index 1df0624268..31689d196c 100644 --- a/source/include/acrestyp.h +++ b/source/include/acrestyp.h @@ -927,8 +927,10 @@ typedef struct acpi_pci_routing_table UINT32 Pin; UINT64 Address; /* here for 64-bit alignment */ UINT32 SourceIndex; - char Source[4]; /* pad to 64 bits so sizeof() works in all cases */ - + union { + char Pad[4]; /* pad to 64 bits so sizeof() works in all cases */ + ACPI_FLEX_ARRAY(char, Source); + }; } ACPI_PCI_ROUTING_TABLE; #endif /* __ACRESTYP_H__ */