On Fri, 8 May 2026 at 11:47, Peter Maydell <[email protected]> wrote:
>
> The C standard doesn't always guarantee that struct and union padding
> bits are zero initialized, even if the code initializes a struct.
> For QEMU, this is potentially problematic, because we often have
> structs that match data structures in guest memory, where we
> initialize them and then bulk copy them into the guest.  If the
> compiler didn't zero init the whole of the memory containing the
> struct, we could potentially leak random data from the host into the
> guest via the padding bytes.
>
> We already use -ftrivial-auto-var-init=zero, which will zero out
> padding in many of these cases, but -fzero-init-padding-bits=all
> closes some gaps, for example cases where we initialize a
> variable with a struct initializer, and cases involving unions.
>
> Follow the Linux kernel in using both options. Compare kernel
> commit dce4aab8441 ("kbuild: Use -fzero-init-padding-bits=all").
>
> This option exists in gcc-15 and above; it's not supported
> by clang, but clang documents that it guarantees zero init
> of these cases always:
> https://clang.llvm.org/docs/LanguageExtensions.html#union-and-aggregate-initialization-in-c
> Older gcc which don't have the option behave as if it were set.
>
> (These options are passed through the cc.get_supported_arguments()
> filter, so we don't need to do anything extra to avoid passing it to
> a compiler that doesn't recognize it.)
>
> Cc: [email protected]
> Signed-off-by: Peter Maydell <[email protected]>
> ---
> CC stable just as a precautionary thing; it's safe and we
> might as well make sure the hardening options are set there.
> ---
>  meson.build | 6 ++++++
>  1 file changed, 6 insertions(+)
>
> diff --git a/meson.build b/meson.build
> index 5fbdc75a0f..d3df10eeef 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -684,6 +684,12 @@ hardening_flags = [
>      # it harder to take advantage of uninitialized stack
>      # data to drive exploits
>      '-ftrivial-auto-var-init=zero',
> +    # Ensure GCC zero-initializes padding bits and trailing fields in
> +    # unions. This avoids potentially leaking host data into the guest
> +    # when we init a struct and copy it into guest memory.  GCC 15 and

Whoops, I meant to say "GCC before GCC 15" here; the commit message
is correct in saying GCC 15 is where the option first appears.

> +    # clang don't have this, but they zero the padding and trailing
> +    # portions of a union by default.
> +    '-fzero-init-padding-bits=all',
>  ]
>
>  # Zero out registers used during a function call
> --
> 2.43.0
>

thanks
-- PMM

Reply via email to