[clang] [Clang][Sema]: Allow flexible arrays in unions and alone in structs (PR #84428)

Kees Cook via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 12 13:08:15 PDT 2024


kees wrote:

> That one ends up not being a problem, but presumably you are wanting to change that top-level 'struct' to be a 'union'?

No, I want to collapse the entire macro into just `TYPE NAME[]`. Right now the Linux kernel uses the `DECLARE_FLEX_ARRAY` macro _in_ over 200 unions and structs. For example:
```
struct iwl_tx_cmd {
    ...
        union {
                DECLARE_FLEX_ARRAY(u8, payload);
                DECLARE_FLEX_ARRAY(struct ieee80211_hdr, hdr);
        };
};
```
or
```
struct pda_antenna_gain {
        DECLARE_FLEX_ARRAY(struct {
                u8 gain_5GHz;   /* 0.25 dBi units */
                u8 gain_2GHz;   /* 0.25 dBi units */
        } __packed, antenna);
} __packed;
```
or
```
struct coreboot_device {
        struct device dev;
        union {
                struct coreboot_table_entry entry;
                struct lb_cbmem_ref cbmem_ref;
                struct lb_cbmem_entry cbmem_entry;
                struct lb_framebuffer framebuffer;
                DECLARE_FLEX_ARRAY(u8, raw);
        };
};
```
> What is the problem with making it `TYPE NAME[0];` ?

Because these are not 0-sized arrays. To have unambiguous mitigation of array and buffer overflows, the compiler must have explicitly defined array sizes. The Linux kernel uses both `-fstrict-flex-array=3` to get rid of all the horrible "fake" flexible arrays (since it was ambiguous and forced GCC and Clang to leave trailing arrays uncovered by the array-bounds sanitizer, `__builtin_object_size()`, and `__builtin_dynamic_object_size()`), and the `counted_by` attribute to gain deterministic size information. Note that with `counted_by`, a 0-sized array is a perfectly valid size, so there is no such thing has "just ignore 0-sized arrays". The point is to gain determinism. We spent 6 years cleaning this up already. Lots of details here:
https://people.kernel.org/kees/bounded-flexible-arrays-in-c

Basically, Linux needed to kill the "if it's a trailing array, it's a flexible array" extension, without removing the "flex arrays can be in unions" extension. The former was solved with GCC and Clang's addition of the `-fstrict-flex-arrays=3` option). The latter was accomplished by bypassing GCC and Clang's syntax checking, but I'd prefer that the extension to support flex arrays in unions just be properly extended to C99 flex arrays to avoid the syntactic hack. (i.e. it's already possible with the hack; why make the hack necessary?)


https://github.com/llvm/llvm-project/pull/84428


More information about the cfe-commits mailing list