diff mbox series

[v2,3/3] kbuild: Use -fzero-init-padding-bits=all

Message ID 20250127191031.245214-3-kees@kernel.org (mailing list archive)
State New
Headers show
Series kbuild: Use -fzero-init-padding-bits=all | expand

Commit Message

Kees Cook Jan. 27, 2025, 7:10 p.m. UTC
GCC 15 introduces a regression in "= { 0 }" style initialization of
unions that Linux has depended on for eliminating uninitialized variable
contents. GCC does not seem likely to fix it[1], instead suggesting[2]
that affected projects start using -fzero-init-padding-bits=unions.

To avoid future surprises beyond just the current situation with unions,
enable -fzero-init-padding-bits=all when available (GCC 15+). This will
correctly zero padding bits in unions and structs that might have been
left uninitialized, and will make sure there is no immediate regression
in union initializations. As seen in the stackinit KUnit selftest union
cases, which were passing before, were failing under GCC 15:

    not ok 18 test_small_start_old_zero
    ok 29 test_small_start_dynamic_partial # SKIP XFAIL uninit bytes: 63
    ok 32 test_small_start_assigned_dynamic_partial # SKIP XFAIL uninit bytes: 63
    ok 67 test_small_start_static_partial # SKIP XFAIL uninit bytes: 63
    ok 70 test_small_start_static_all # SKIP XFAIL uninit bytes: 56
    ok 73 test_small_start_dynamic_all # SKIP XFAIL uninit bytes: 56
    ok 82 test_small_start_assigned_static_partial # SKIP XFAIL uninit bytes: 63
    ok 85 test_small_start_assigned_static_all # SKIP XFAIL uninit bytes: 56
    ok 88 test_small_start_assigned_dynamic_all # SKIP XFAIL uninit bytes: 56

The above all now pass again with -fzero-init-padding-bits=all added.

This also fixes the following cases for struct initialization that had
been XFAIL until now because there was no compiler support beyond the
larger "-ftrivial-auto-var-init=zero" option:

    ok 38 test_small_hole_static_all # SKIP XFAIL uninit bytes: 3
    ok 39 test_big_hole_static_all # SKIP XFAIL uninit bytes: 124
    ok 40 test_trailing_hole_static_all # SKIP XFAIL uninit bytes: 7
    ok 42 test_small_hole_dynamic_all # SKIP XFAIL uninit bytes: 3
    ok 43 test_big_hole_dynamic_all # SKIP XFAIL uninit bytes: 124
    ok 44 test_trailing_hole_dynamic_all # SKIP XFAIL uninit bytes: 7
    ok 58 test_small_hole_assigned_static_all # SKIP XFAIL uninit bytes: 3
    ok 59 test_big_hole_assigned_static_all # SKIP XFAIL uninit bytes: 124
    ok 60 test_trailing_hole_assigned_static_all # SKIP XFAIL uninit bytes: 7
    ok 62 test_small_hole_assigned_dynamic_all # SKIP XFAIL uninit bytes: 3
    ok 63 test_big_hole_assigned_dynamic_all # SKIP XFAIL uninit bytes: 124
    ok 64 test_trailing_hole_assigned_dynamic_all # SKIP XFAIL uninit bytes: 7

All of the above now pass when built under GCC 15. Tests can be seen
with:

    ./tools/testing/kunit/kunit.py run stackinit --arch=x86_64 \
        --make_option CC=gcc-15

Clang continues to fully initialize these kinds of variables[3] with
additional flags.

Suggested-by: Jakub Jelinek <jakub@redhat.com>
Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118403 [1]
Link: https://lore.kernel.org/linux-toolchains/Z0hRrrNU3Q+ro2T7@tucnak/ [2]
Link: https://github.com/llvm/llvm-project/commit/7a086e1b2dc05f54afae3591614feede727601fa [3]
Reviewed-by: Nathan Chancellor <nathan@kernel.org>
Signed-off-by: Kees Cook <kees@kernel.org>
---
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Nicolas Schier <nicolas@fjasle.eu>
Cc: linux-kbuild@vger.kernel.org
---
 scripts/Makefile.extrawarn | 3 +++
 1 file changed, 3 insertions(+)

Comments

Kees Cook Jan. 27, 2025, 7:54 p.m. UTC | #1
On Mon, Jan 27, 2025 at 11:10:28AM -0800, Kees Cook wrote:
> Clang continues to fully initialize these kinds of variables[3] with
> additional flags.

Typo: "with" should be "without". I've fixed this locally.
Masahiro Yamada Jan. 30, 2025, 2:35 a.m. UTC | #2
On Tue, Jan 28, 2025 at 4:10 AM Kees Cook <kees@kernel.org> wrote:
>
> GCC 15 introduces a regression in "= { 0 }" style initialization of
> unions that Linux has depended on for eliminating uninitialized variable
> contents. GCC does not seem likely to fix it[1], instead suggesting[2]
> that affected projects start using -fzero-init-padding-bits=unions.
>
> To avoid future surprises beyond just the current situation with unions,
> enable -fzero-init-padding-bits=all when available (GCC 15+). This will
> correctly zero padding bits in unions and structs that might have been
> left uninitialized, and will make sure there is no immediate regression
> in union initializations. As seen in the stackinit KUnit selftest union
> cases, which were passing before, were failing under GCC 15:
>
>     not ok 18 test_small_start_old_zero
>     ok 29 test_small_start_dynamic_partial # SKIP XFAIL uninit bytes: 63
>     ok 32 test_small_start_assigned_dynamic_partial # SKIP XFAIL uninit bytes: 63
>     ok 67 test_small_start_static_partial # SKIP XFAIL uninit bytes: 63
>     ok 70 test_small_start_static_all # SKIP XFAIL uninit bytes: 56
>     ok 73 test_small_start_dynamic_all # SKIP XFAIL uninit bytes: 56
>     ok 82 test_small_start_assigned_static_partial # SKIP XFAIL uninit bytes: 63
>     ok 85 test_small_start_assigned_static_all # SKIP XFAIL uninit bytes: 56
>     ok 88 test_small_start_assigned_dynamic_all # SKIP XFAIL uninit bytes: 56
>
> The above all now pass again with -fzero-init-padding-bits=all added.
>
> This also fixes the following cases for struct initialization that had
> been XFAIL until now because there was no compiler support beyond the
> larger "-ftrivial-auto-var-init=zero" option:
>
>     ok 38 test_small_hole_static_all # SKIP XFAIL uninit bytes: 3
>     ok 39 test_big_hole_static_all # SKIP XFAIL uninit bytes: 124
>     ok 40 test_trailing_hole_static_all # SKIP XFAIL uninit bytes: 7
>     ok 42 test_small_hole_dynamic_all # SKIP XFAIL uninit bytes: 3
>     ok 43 test_big_hole_dynamic_all # SKIP XFAIL uninit bytes: 124
>     ok 44 test_trailing_hole_dynamic_all # SKIP XFAIL uninit bytes: 7
>     ok 58 test_small_hole_assigned_static_all # SKIP XFAIL uninit bytes: 3
>     ok 59 test_big_hole_assigned_static_all # SKIP XFAIL uninit bytes: 124
>     ok 60 test_trailing_hole_assigned_static_all # SKIP XFAIL uninit bytes: 7
>     ok 62 test_small_hole_assigned_dynamic_all # SKIP XFAIL uninit bytes: 3
>     ok 63 test_big_hole_assigned_dynamic_all # SKIP XFAIL uninit bytes: 124
>     ok 64 test_trailing_hole_assigned_dynamic_all # SKIP XFAIL uninit bytes: 7
>
> All of the above now pass when built under GCC 15. Tests can be seen
> with:
>
>     ./tools/testing/kunit/kunit.py run stackinit --arch=x86_64 \
>         --make_option CC=gcc-15
>
> Clang continues to fully initialize these kinds of variables[3] with
> additional flags.
>
> Suggested-by: Jakub Jelinek <jakub@redhat.com>
> Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118403 [1]
> Link: https://lore.kernel.org/linux-toolchains/Z0hRrrNU3Q+ro2T7@tucnak/ [2]
> Link: https://github.com/llvm/llvm-project/commit/7a086e1b2dc05f54afae3591614feede727601fa [3]
> Reviewed-by: Nathan Chancellor <nathan@kernel.org>
> Signed-off-by: Kees Cook <kees@kernel.org>
> ---



Acked-by: Masahiro Yamada <masahiroy@kernel.org>






> Cc: Masahiro Yamada <masahiroy@kernel.org>
> Cc: Nicolas Schier <nicolas@fjasle.eu>
> Cc: linux-kbuild@vger.kernel.org
> ---
>  scripts/Makefile.extrawarn | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn
> index 1d13cecc7cc7..eb719f6d8d53 100644
> --- a/scripts/Makefile.extrawarn
> +++ b/scripts/Makefile.extrawarn
> @@ -77,6 +77,9 @@ KBUILD_CFLAGS += $(call cc-option,-Werror=designated-init)
>  # Warn if there is an enum types mismatch
>  KBUILD_CFLAGS += $(call cc-option,-Wenum-conversion)
>
> +# Explicitly clear padding bits during variable initialization
> +KBUILD_CFLAGS += $(call cc-option,-fzero-init-padding-bits=all)
> +
>  KBUILD_CFLAGS += -Wextra
>  KBUILD_CFLAGS += -Wunused
>
> --
> 2.34.1
>
diff mbox series

Patch

diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn
index 1d13cecc7cc7..eb719f6d8d53 100644
--- a/scripts/Makefile.extrawarn
+++ b/scripts/Makefile.extrawarn
@@ -77,6 +77,9 @@  KBUILD_CFLAGS += $(call cc-option,-Werror=designated-init)
 # Warn if there is an enum types mismatch
 KBUILD_CFLAGS += $(call cc-option,-Wenum-conversion)
 
+# Explicitly clear padding bits during variable initialization
+KBUILD_CFLAGS += $(call cc-option,-fzero-init-padding-bits=all)
+
 KBUILD_CFLAGS += -Wextra
 KBUILD_CFLAGS += -Wunused