On Thu, Feb 25, 2021 at 12:15:01PM -0600, Qing Zhao wrote: > > On Feb 24, 2021, at 10:41 PM, Kees Cook <keesc...@chromium.org> wrote: > > [...] > > test_stackinit: trailing_hole_none ok > > test_stackinit: packed_none ok > > test_stackinit: user ok > > test_stackinit: failures: 8 > > Does the above testing include “pattern initialization” in addition to “zero > initialization”?
This was from the zero-init case. I've just tested pattern-init now and it actually crashes GCC. I minimized the test case to this: $ cat main.i a() { char b[1]; } $ gcc -ftrivial-auto-var-init=pattern -c /dev/null main.i main.i:1:1: warning: return type defaults to ‘int’ [-Wimplicit-int] 1 | a() { char b[1]; } | ^ main.i: In function ‘a’: main.i:1:12: internal compiler error: in gimplify_init_ctor_eval, at gimplify.c:4873 1 | a() { char b[1]; } | ^ 0x69740d gimplify_init_ctor_eval ../../../gcc/gcc/gimplify.c:4873 0xb5ac8f gimplify_init_constructor ../../../gcc/gcc/gimplify.c:5320 0xb6b68a gimplify_modify_expr ../../../gcc/gcc/gimplify.c:5952 0xb533ba gimplify_expr(tree_node**, gimple**, gimple**, bool (*)(tree_node*), int) ../../../gcc/gcc/gimplify.c:14262 0xb56b26 gimplify_stmt(tree_node**, gimple**) ../../../gcc/gcc/gimplify.c:7056 0xb68e6e gimplify_and_add(tree_node*, gimple**) ../../../gcc/gcc/gimplify.c:489 0xb68e6e gimple_add_init_for_auto_var ../../../gcc/gcc/gimplify.c:1892 0xb68e6e gimplify_decl_expr ../../../gcc/gcc/gimplify.c:2010 0xb53bd6 gimplify_expr(tree_node**, gimple**, gimple**, bool (*)(tree_node*), int) ../../../gcc/gcc/gimplify.c:14459 0xb56b26 gimplify_stmt(tree_node**, gimple**) ../../../gcc/gcc/gimplify.c:7056 0xb5727d gimplify_bind_expr ../../../gcc/gcc/gimplify.c:1421 0xb536f0 gimplify_expr(tree_node**, gimple**, gimple**, bool (*)(tree_node*), int) ../../../gcc/gcc/gimplify.c:14463 0xb6ccc9 gimplify_stmt(tree_node**, gimple**) ../../../gcc/gcc/gimplify.c:7056 0xb6ccc9 gimplify_body(tree_node*, bool) ../../../gcc/gcc/gimplify.c:15498 0xb6d0ed gimplify_function_tree(tree_node*) ../../../gcc/gcc/gimplify.c:15652 0x9ae8d7 cgraph_node::analyze() ../../../gcc/gcc/cgraphunit.c:670 0x9b13a7 analyze_functions ../../../gcc/gcc/cgraphunit.c:1233 0x9b1f9d symbol_table::finalize_compilation_unit() ../../../gcc/gcc/cgraphunit.c:2511 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <https://gcc.gnu.org/bugs/> for instructions. > > struct test_..._hole instance = { .two = ..., }; > > > > or > > > > struct test_..._hole instance = { .one = ..., > > .two = ..., > > .three = ..., > > .four = ..., > > > > }; > > So, when the structure variables are not statically initialized, all the > paddings are initialized correctly by the compiler? For the zero case, yes. (Usually such happen via copies into stack from from .rodata sections, or accidentally from already-initialized copies.) > In the current implementation, when the auto variable is explicitly > initialized, compiler will do nothing. > Looks like for structure variables we need some special handling to > initialize the paddings. > Need to study this a little bit and see how to fix it. Deterministic padding init is a big part of this defense since that's where the bulk of the really hard-to-find problems have existed (i.e. in padding holes in structures that got copied around). > > The last case is for switch variables outside of case statements, like > > "var" here: > > > > switch (path) { > > unsigned long var; > > > > case ..: > > ... > > case ..: > > ... > > ... > > } > > > > Will study this case more. For the kernel, this is a low priority, since I purged the code of all variable declarations outside of an execution path[1]. For reference, here's the Clang bug for the same problem[2] (though latest Clang git appears to no longer exhibit this issue, so they may have fixed it). -Kees [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?qt=grep&q=Distribute+switch+variables+for+initialization [2] https://bugs.llvm.org/show_bug.cgi?id=44916 -- Kees Cook