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