Skip to content

Consider -fzero-init-padding-bits=all for C and C++ Compiler Hardening Guide #857

Open
@thomasnyman

Description

@thomasnyman

GCC 15 is expected to alter its behavior with respect to initializing padding
bits in unions and structures where the standard doesn't require it, e.g.,

void foo (void)
{
	union U { int a; long b[64]; };
        /* C23 requires padding bits to be cleared here.  */
	union U u = {};
	
        /* In GCC 14 an earlier, this clear everything, but only clears v.a in GCC 15 by default.  */
	union U v = {0};
}

void bar (void)
{
	struct S { char a; int b; };
	/* C23 requires padding bits to be cleared here.  */
	struct S s = {};
	/* n GCC 14 an earlier this would also clear padding bits, but in GCC 15 this is not longer the case. */
	struct S t = { 1, 2 };
}

Developers might want to retain the behavior in GCC 14 and earlier to avoid uninitialized padding bits from leaking information in cases where structures are passed across security boundaries, e.g., userspace / kernelspace boundary, to sandboxed code etc. In the case of unions the -fzero-init-padding-bits=unions can be used to restore previous behavior and -fzero-init-padding-bits=all restores the GCC 14 behavior in both of the above cases.

Another alternative is the use of the __builtin_clear_padding though it doesn't clear bits in unions unless they are padding bits for all possible members.

Thanks to @fuhsnn for pointing this out (I was taking notes)

Resources:

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions