[PATCH] D126864: [clang] Introduce -fstrict-flex-arrays=<n> for stricter handling of flexible arrays

Kees Cook via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Jul 13 16:34:16 PDT 2022


kees added a comment.

In D126864#3646854 <https://reviews.llvm.org/D126864#3646854>, @jyknight wrote:

> In D126864#3645994 <https://reviews.llvm.org/D126864#3645994>, @kees wrote:
>
>> I should clarify: I still need the =3 mode. Since sizeof([0]) == 0 and sizeof([]) == error, they are being treated differently already by the compiler causing bugs in Linux. The kernel must still have a way to reject the _use_ of a [0] array. We cannot reject _declaration_ of them due to userspace API.
>
> Looks like the linux kernel is currently chock-full of zero-length-arrays which are actually intended/required to work as flexible array members. Do you have a pending patch to convert all of them to [] which should be?

Well, yes and no. It's been a multi-year on-going effort. Though it's actually complete for the kernel now as of v5.18:
https://github.com/KSPP/linux/issues/78

What remains is the userspace headers. The _real_ pain has been the 1-element arrays. Ugh. The master bug is here:
https://github.com/KSPP/linux/issues/21

> If you're saying you absolutely need this mode -- which I still believe would be nonsensical to provide -- I'd like to see the set of concrete examples you cannot otherwise deal with.

I have several goals. The most important is making all the fixed-sized trailing arrays are NOT treated as flexible arrays so that `__builtin_object_size` will work as expected for Linux's FORTIFY implementation and `-fstrict-flex-arrays=2` certainly solves that. However, then we're left with all the 0-element arrays, which need to be cleaned up because they don't behave the same as true flexible arrays. For example, with `sizeof`; the kernel has dealt with allocation size bugs relating to `sizeof` being used against 0-element arrays (which _should_ have caused a build failure if it were a true flexible array and the bug would have been immediately found), and I would like to make sure those can never happen again.

If this were any other code base, I could just use `-Wzero-length-array`, but the scattered ancient userspace APIs need to live on until $forever.

And if this were any other code base, I could use `#pragma`, but it's frown on in general, and is going to be met with even greater resistance in userspace API headers, especially given that it will need to be `#ifdef`ed for clang vs gcc, and then tweaked again once GCC gains the option, which would then need to be version checked. (This is why `#pragma` is strongly discouraged: Linux has a whole system for doing compiler behavior detection for its internal headers and build system, but such things don't exist for the userspace headers.)

So given the behavioral differences that already existed between true flexible arrays and 0-element arrays, I'd wanted to have a way to turn off _all_ the flexible array "extensions". I never wanted these different levels for `-fstrict-flex-arrays`. :) I want the complete disabling of all the extensions that were creating inconsistent behaviors. But to lose the ability to disable the 0-is-flexible would be disappointing, but if I absolutely have no choice, I can live with it. Given Linux will be the first user of this option, and the reason for this option being created, I'd _much_ rather have it doing what's needed, though. :)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D126864/new/

https://reviews.llvm.org/D126864



More information about the cfe-commits mailing list