fosstodon.org is one of the many independent Mastodon servers you can use to participate in the fediverse.
Fosstodon is an invite only Mastodon instance that is open to those who are interested in technology; particularly free & open source software. If you wish to join, contact us for an invite.

Administered by:

Server stats:

11K
active users

Kees Cook :tux:

Well I guess everyone everywhere will want to use -fzero-init-padding-bits=all when updating to GCC15 to avoid regressing their uninitialized variable mitigations... Why in the world would the C standard committee work to make things *less* safe by default??!

Edit: this appears to be a decision on GCC's part and not a new change from the C committee. (See down-thread.)

infosec.exchange/@edmonds/1138

Infosec ExchangeRobert Edmonds (@edmonds@infosec.exchange)@bert_hubert@fosstodon.org Oh yes I was just idly wondering if that would work, I've already poured over the disassembly and seen the movl's and movb's in the actual broken code 🙂 In the upcoming gcc 15 they have introduced new behavior due to C23 which allows for a standards compliant "= {}" initializer in C that zeroes all the bits (https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2900.htm), and they've, coincidentally, taken the opportunity to change the behavior of the "= {0}" initializer from one standards compliant interpretation (zero all the bits) to another standards compliant interpretation (don't necessarily zero all the bits). C23 6.2.6.1 paragraph 7 (same as in previous versions of the C standard): > When a value is stored in a member of an object of union type, the bytes of the object representation that do not correspond to that member but do correspond to other members take unspecified values. There is a new -fzero-init-padding-bits= option in gcc 15 that controls the behavior (https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#index-fzero-init-padding-bits_003dvalue) which I found completely confusing until I realized gcc uses the term "union padding bits" in a sort of unconventional way. But you don't really want to rely on those new flags in gcc 15 if you can reorder the members of the union and rely on standards compliant "= {0}" initialization. In that case, always remember to put the biggest, strongest member of your union at the front if you want it initialized, just like a real union 😃

@kees It's a ploy by static analysis companies to sell you more checks....

@kees uh, wth. This is depended on all over the place.

@kees I do not know why GCC made this change, but it is *not* helpful to blame committee (that certainly failed to close this loophole) but also did not make it less safe relative to before. In fact, this is exactly the misdirection that lets compiler vendors get a away with this nonsense. (edit: note that I thought this is about {} not fully initialization but GCC gets this right, I am less critical about the {0} change)

@uecker This looked like it was GCC trying to follow the standard. Is that not accurate? Because that option ("the default setting is 'standard'") really seems to be saying so. Whatever the case, it's a regression in behavior.

@kees The standard does not require this new behavior and did not change in this regard. It seems to allow this because we somehow failed to close this loophole and it is disappointing to see that GCC did this change for optimization. (edit: note that I thought this is about {} not fully initialization but GCC gets this right, I am less critical about the {0} change)

@uecker What's going on with GCC claiming this is somehow related to C23? This is very confusing.

@kees The documentation link cites C23 empty initialization {} as an example and that is new, but { 0 } does the same.

@uecker It's more than that, though. For example, see this bug, where C23 seems to be the rationale for the change:
gcc.gnu.org/bugzilla/show_bug.

gcc.gnu.org118403 – uninitialized warning with automatic union

@kees It is indeed a bit different than I thought. The issue is that C23 introduced empty initialization with the requirement to initialize padding. This does not include bytes in unions of other members (the loophole) but it seems gcc / clang still clear those (as intended!). But GCC also (coincidentally) decided to optimize zero init { 0 } as already allowed previously (no change in the standard). (Edit: the {} was working also before, so the patch was just the optimization of { 0 })

@uecker @kees if I'm reading this correctly… Why would anyone ever use {0} over {} ?

@Aissen @kees To avoid initialization in some cases. Or when one has to use a compiler that does not support {}.

@Aissen @uecker @kees it used to be required, `{}` was a gcc extension iirc (it even used to warn differently between clang and gcc, so whether you used `{}` or `{0}` one of the compilers would yell at you), so it's going to exist in both forms in lots of places. the problem is that some of those places are now going to be bugs. (but you're right that you probably should lose the habit and start using `{}` if your compiler support matrix allows it)

@dotstdy @uecker @kees thanks, I guess I was too accustomed to using only GCC.

@kees The problem is that in the standard committee the vendors will always argue that what they do is what their customers want. So users blaming WG14 instead the compiler vendor responsible is weakening our power to fix it instead of helping.

@kees they didn't, GCC changed The way they comply

@kees They did send aail about this around or before Christmas about this to lkml btw.

@thesamesam @kees @brauner @uecker @pinskia Okay, this might be me just being stupid here, but in "PR118575", does "PR" stand for "problem report" or something else?

@kees @brauner @uecker @pinskia Okay, I think we're actually good already, and there's no effect on existing mitigations (see my comment on the bug). If I'm wrong, let's chat over there with testcase(s) and poke at it.