Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace fake flexible arrays with actual flexible array members #813

Merged
merged 4 commits into from Feb 7, 2023

Conversation

kees
Copy link
Contributor

@kees kees commented Nov 18, 2022

This continues earlier C99 work to modernize the code to work correctly with compile-time and run-time bounds checkers.

@acpibob
Copy link
Contributor

acpibob commented Nov 18, 2022 via email

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.
Use ACPI_FLEX_ARRAY() helper to define flexible array member alone in a
struct. Fixes issue acpica#812.
Similar to commit 7ba2f3d ("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).
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.
@kees
Copy link
Contributor Author

kees commented Nov 18, 2022

OK, but I’m thinking that using these “new” structures will require changes that affect both the Data Table Compiler and the Data Table disassembler.

I don't know what this means. :) How can I find/test these?

@acpibob
Copy link
Contributor

acpibob commented Nov 18, 2022 via email

@rafaeljw
Copy link
Contributor

rafaeljw commented Dec 8, 2022

@acpibob What if this change is made locally in Linux? I don't think it will become unmanageable going forward.

Copy link
Contributor

@rafaeljw rafaeljw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It fixes an existing build issue and I don't see problems with it.

roxell pushed a commit to roxell/linux that referenced this pull request Jan 19, 2023
Functionally identical to ACPICA upstream pull request 813:
acpica/acpica#813

One-element arrays (and multi-element arrays being treated as
dynamically sized) are deprecated[1] and are being replaced with
flexible array members in support of the ongoing efforts to tighten the
FORTIFY_SOURCE routines on memcpy(), correctly instrument array indexing
with UBSAN_BOUNDS, and to globally enable -fstrict-flex-arrays=3.

Replace one-element array with flexible-array member in struct
acpi_resource_extended_irq. Replace 4-byte fixed-size array with 4-byte
padding in a union with a flexible-array member in struct
acpi_pci_routing_table.

This results in no differences in binary output.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Len Brown <lenb@kernel.org>
Cc: Robert Moore <robert.moore@intel.com>
Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
Cc: linux-acpi@vger.kernel.org
Link: https://lore.kernel.org/all/20221118181538.never.225-kees@kernel.org/
Signed-off-by: Kees Cook <keescook@chromium.org>
intel-lab-lkp pushed a commit to intel-lab-lkp/linux that referenced this pull request Jan 20, 2023
Functionally identical to ACPICA upstream pull request 813:
acpica/acpica#813

One-element arrays (and multi-element arrays being treated as
dynamically sized) are deprecated[1] and are being replaced with
flexible array members in support of the ongoing efforts to tighten the
FORTIFY_SOURCE routines on memcpy(), correctly instrument array indexing
with UBSAN_BOUNDS, and to globally enable -fstrict-flex-arrays=3.

Replace one-element array with flexible-array member in struct
acpi_resource_extended_irq. Replace 4-byte fixed-size array with 4-byte
padding in a union with a flexible-array member in struct
acpi_pci_routing_table.

This results in no differences in binary output.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Len Brown <lenb@kernel.org>
Cc: Robert Moore <robert.moore@intel.com>
Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
Cc: linux-acpi@vger.kernel.org
Link: https://lore.kernel.org/all/20221118181538.never.225-kees@kernel.org/
Signed-off-by: Kees Cook <keescook@chromium.org>
intel-lab-lkp pushed a commit to intel-lab-lkp/linux that referenced this pull request Jan 28, 2023
One-element arrays (and multi-element arrays being treated as
dynamically sized) are deprecated[1] and are being replaced with
flexible array members in support of the ongoing efforts to tighten the
FORTIFY_SOURCE routines on memcpy(), correctly instrument array indexing
with UBSAN_BOUNDS, and to globally enable -fstrict-flex-arrays=3.

Replace one-element array with flexible-array member in struct
acpi_resource_extended_irq. Replace 4-byte fixed-size array with 4-byte
padding in a union with a flexible-array member in struct
acpi_pci_routing_table.

This results in no differences in binary output.

Link: acpica/acpica#813
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
*/
#define ACPI_FLEX_ARRAY(TYPE, NAME) \
struct { \
struct { } __Empty_ ## NAME; \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty structs are a GNU extension

* limitation.
*/
#define ACPI_FLEX_ARRAY(TYPE, NAME) \
struct { \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anonymous structs require C11 (or a compiler that adds them as an extension to pre-C11)

@@ -1550,7 +1550,7 @@ enum AcpiMadtLpcPicVersion {

typedef struct acpi_madt_oem_data
{
UINT8 OemData[];
ACPI_FLEX_ARRAY(UINT8, OemData);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Structs with flexible array members can't be nested inside other structs, only unions, without extensions

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this works around a deficiency in the C spec using GNU extensions which have been supported by GCC and Clang for a very long time.

Copy link
Contributor

@jrtc27 jrtc27 Feb 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realise that, but you're just swapping one extension for another which doesn't achieve anything as far as I can tell other than adding extra complication.

If your goal is to avoid extensions then just typedef UINT8 ACPI_MADT_OEM_DATA[], which is an API break but just requires changing Expr->OemData to (*Expr).

@acpibob
Copy link
Contributor

acpibob commented Feb 7, 2023

OK, I'll try this PR as it stands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants