Re: [PATCH v2 2/3] stackinit: Add union initialization to selftests

From: Geert Uytterhoeven
Date: Mon Feb 03 2025 - 09:55:06 EST


Hi Kees,

On Mon, 27 Jan 2025 at 20:11, Kees Cook <kees@xxxxxxxxxx> wrote:
> The stack initialization selftests were checking scalars, strings,
> and structs, but not unions. Add union tests (which are mostly identical
> setup to structs). This catches the recent union initialization behavioral
> changes seen in GCC 15. Before GCC 15, this new test passes:
>
> ok 18 test_small_start_old_zero
>
> With GCC 15, it fails:
>
> not ok 18 test_small_start_old_zero
>
> Specifically, a union with a larger member where a smaller member is
> initialized with the older "= { 0 }" syntax:
>
> union test_small_start {
> char one:1;
> char two;
> short three;
> unsigned long four;
> struct big_struct {
> unsigned long array[8];
> } big;
> };
>
> This is a regression in compiler behavior that Linux has depended on.
> GCC does not seem likely to fix it, instead suggesting that affected
> projects start using -fzero-init-padding-bits=unions:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118403
>
> Signed-off-by: Kees Cook <kees@xxxxxxxxxx>

I ran stackinit_kunit from v6.14-rc1 on m68k under ARAnyM.
All small_start tests failed:

KTAP version 1
1..1
KTAP version 1
# Subtest: stackinit
# module: stackinit_kunit
1..108
ok 1 test_u8_zero
ok 2 test_u16_zero
ok 3 test_u32_zero
ok 4 test_u64_zero
ok 5 test_char_array_zero
ok 6 test_small_hole_zero
ok 7 test_big_hole_zero
ok 8 test_trailing_hole_zero
ok 9 test_packed_zero
ok 10 test_small_hole_old_zero
ok 11 test_big_hole_old_zero
ok 12 test_trailing_hole_old_zero
ok 13 test_packed_old_zero
ok 14 test_same_sizes_zero
# test_small_start_zero: ASSERTION FAILED at lib/stackinit_kunit.c:428
Expected stackinit_range_contains(fill_start, fill_size,
target_start, target_size) to be true, but is false

stackframe was not the same between calls!? (fill 32 wide, target offset by -12)
not ok 15 test_small_start_zero
ok 16 test_small_end_zero
ok 17 test_same_sizes_old_zero
# test_small_start_old_zero: ASSERTION FAILED at lib/stackinit_kunit.c:429
Expected stackinit_range_contains(fill_start, fill_size,
target_start, target_size) to be true, but is false

stackframe was not the same between calls!? (fill 32 wide, target offset by -12)
not ok 18 test_small_start_old_zero
ok 19 test_small_end_old_zero
ok 20 test_small_hole_dynamic_partial
ok 21 test_big_hole_dynamic_partial
ok 22 test_trailing_hole_dynamic_partial
ok 23 test_packed_dynamic_partial
ok 24 test_small_hole_assigned_dynamic_partial
ok 25 test_big_hole_assigned_dynamic_partial
ok 26 test_trailing_hole_assigned_dynamic_partial
ok 27 test_packed_assigned_dynamic_partial
ok 28 test_same_sizes_dynamic_partial
# test_small_start_dynamic_partial: ASSERTION FAILED at
lib/stackinit_kunit.c:438
Expected stackinit_range_contains(fill_start, fill_size,
target_start, target_size) to be true, but is false

stackframe was not the same between calls!? (fill 32 wide, target offset by -12)
not ok 29 test_small_start_dynamic_partial
ok 30 test_small_end_dynamic_partial
ok 31 test_same_sizes_assigned_dynamic_partial
# test_small_start_assigned_dynamic_partial: ASSERTION FAILED at
lib/stackinit_kunit.c:441
Expected stackinit_range_contains(fill_start, fill_size,
target_start, target_size) to be true, but is false

stackframe was not the same between calls!? (fill 32 wide, target offset by -12)
not ok 32 test_small_start_assigned_dynamic_partial
ok 33 test_small_end_assigned_dynamic_partial
ok 34 test_small_hole_static_partial
ok 35 test_big_hole_static_partial
ok 36 test_trailing_hole_static_partial
ok 37 test_packed_static_partial
ok 38 test_small_hole_static_all
ok 39 test_big_hole_static_all
ok 40 test_trailing_hole_static_all
ok 41 test_packed_static_all
ok 42 test_small_hole_dynamic_all
ok 43 test_big_hole_dynamic_all
ok 44 test_trailing_hole_dynamic_all
ok 45 test_packed_dynamic_all
ok 46 test_small_hole_runtime_partial
ok 47 test_big_hole_runtime_partial
ok 48 test_trailing_hole_runtime_partial
ok 49 test_packed_runtime_partial
ok 50 test_small_hole_runtime_all
ok 51 test_big_hole_runtime_all
ok 52 test_trailing_hole_runtime_all
ok 53 test_packed_runtime_all
ok 54 test_small_hole_assigned_static_partial
ok 55 test_big_hole_assigned_static_partial
ok 56 test_trailing_hole_assigned_static_partial
ok 57 test_packed_assigned_static_partial
ok 58 test_small_hole_assigned_static_all
ok 59 test_big_hole_assigned_static_all
ok 60 test_trailing_hole_assigned_static_all
ok 61 test_packed_assigned_static_all
ok 62 test_small_hole_assigned_dynamic_all
ok 63 test_big_hole_assigned_dynamic_all
ok 64 test_trailing_hole_assigned_dynamic_all
ok 65 test_packed_assigned_dynamic_all
ok 66 test_same_sizes_static_partial
# test_small_start_static_partial: ASSERTION FAILED at
lib/stackinit_kunit.c:437
Expected stackinit_range_contains(fill_start, fill_size,
target_start, target_size) to be true, but is false

stackframe was not the same between calls!? (fill 32 wide, target offset by -12)
not ok 67 test_small_start_static_partial
ok 68 test_small_end_static_partial
ok 69 test_same_sizes_static_all
# test_small_start_static_all: ASSERTION FAILED at lib/stackinit_kunit.c:437
Expected stackinit_range_contains(fill_start, fill_size,
target_start, target_size) to be true, but is false

stackframe was not the same between calls!? (fill 32 wide, target offset by -12)
not ok 70 test_small_start_static_all
ok 71 test_small_end_static_all
ok 72 test_same_sizes_dynamic_all
# test_small_start_dynamic_all: ASSERTION FAILED at
lib/stackinit_kunit.c:438
Expected stackinit_range_contains(fill_start, fill_size,
target_start, target_size) to be true, but is false

stackframe was not the same between calls!? (fill 32 wide, target offset by -12)
not ok 73 test_small_start_dynamic_all
ok 74 test_small_end_dynamic_all
ok 75 test_same_sizes_runtime_partial
# test_small_start_runtime_partial: ASSERTION FAILED at
lib/stackinit_kunit.c:439
Expected stackinit_range_contains(fill_start, fill_size,
target_start, target_size) to be true, but is false

stackframe was not the same between calls!? (fill 32 wide, target offset by -12)
not ok 76 test_small_start_runtime_partial
ok 77 test_small_end_runtime_partial
ok 78 test_same_sizes_runtime_all
# test_small_start_runtime_all: ASSERTION FAILED at
lib/stackinit_kunit.c:439
Expected stackinit_range_contains(fill_start, fill_size,
target_start, target_size) to be true, but is false

stackframe was not the same between calls!? (fill 32 wide, target offset by -12)
not ok 79 test_small_start_runtime_all
ok 80 test_small_end_runtime_all
ok 81 test_same_sizes_assigned_static_partial
# test_small_start_assigned_static_partial: ASSERTION FAILED at
lib/stackinit_kunit.c:440
Expected stackinit_range_contains(fill_start, fill_size,
target_start, target_size) to be true, but is false

stackframe was not the same between calls!? (fill 32 wide, target offset by -12)
not ok 82 test_small_start_assigned_static_partial
ok 83 test_small_end_assigned_static_partial
ok 84 test_same_sizes_assigned_static_all
# test_small_start_assigned_static_all: ASSERTION FAILED at
lib/stackinit_kunit.c:440
Expected stackinit_range_contains(fill_start, fill_size,
target_start, target_size) to be true, but is false

stackframe was not the same between calls!? (fill 32 wide, target offset by -12)
not ok 85 test_small_start_assigned_static_all
ok 86 test_small_end_assigned_static_all
ok 87 test_same_sizes_assigned_dynamic_all
# test_small_start_assigned_dynamic_all: ASSERTION FAILED at
lib/stackinit_kunit.c:441
Expected stackinit_range_contains(fill_start, fill_size,
target_start, target_size) to be true, but is false

stackframe was not the same between calls!? (fill 32 wide, target offset by -12)
not ok 88 test_small_start_assigned_dynamic_all
ok 89 test_small_end_assigned_dynamic_all
ok 90 test_small_hole_assigned_copy # SKIP XFAIL uninit bytes: 1
ok 91 test_big_hole_assigned_copy # SKIP XFAIL uninit bytes: 124
ok 92 test_trailing_hole_assigned_copy # SKIP XFAIL uninit bytes: 1
ok 93 test_packed_assigned_copy
ok 94 test_same_sizes_assigned_copy
# test_small_start_assigned_copy: ASSERTION FAILED at
lib/stackinit_kunit.c:442
Expected stackinit_range_contains(fill_start, fill_size,
target_start, target_size) to be true, but is false

stackframe was not the same between calls!? (fill 32 wide, target offset by -12)
not ok 95 test_small_start_assigned_copy
ok 96 test_small_end_assigned_copy
ok 97 test_u8_none
ok 98 test_u16_none
ok 99 test_u32_none
ok 100 test_u64_none
ok 101 test_char_array_none
ok 102 test_switch_1_none # SKIP XFAIL uninit bytes: 80
ok 103 test_switch_2_none # SKIP XFAIL uninit bytes: 80
ok 104 test_small_hole_none
ok 105 test_big_hole_none
ok 106 test_trailing_hole_none
ok 107 test_packed_none
ok 108 test_user
# stackinit: pass:90 fail:13 skip:5 total:108
# Totals: pass:90 fail:13 skip:5 total:108
not ok 1 stackinit

m68k-linux-gnu-gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0, GNU ld (GNU
Binutils for Ubuntu) 2.42
Thanks!

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@xxxxxxxxxxxxxx

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds