https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80414
Bug ID: 80414 Summary: [UBSAN] segfault with -fsanitize=undefined Product: gcc Version: 7.0.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: sanitizer Assignee: unassigned at gcc dot gnu.org Reporter: d.khalikov at partner dot samsung.com CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org, jakub at gcc dot gnu.org, kcc at gcc dot gnu.org Target Milestone: --- Created attachment 41191 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41191&action=edit patch Hello everyone. I got segfault on 32 bit host with -fsanitize=undefined My test case: # cat test.c int main() { long long offset = 10; char array[10]; char c = array[offset]; return 0; } # gcc -o test test.c -fsanitize=undefined -static-libubsan # ./test That happens while checking for bounds-strict option on 32 bit host. As i can see gcc push value of the index to the stack before call __ubsan_handle_out_of_bounds 67 subl $44, %esp 68 movl $10, -32(%ebp) 69 movl $0, -28(%ebp) 70 movl -32(%ebp), %ebx 71 movl -28(%ebp), %esi 72 movl %ebx, %eax 73 cmpl $9, %eax 74 jbe .L2 75 subl $8, %esp 76 pushl %eax 77 pushl $.Lubsan_data0 78 call __ubsan_handle_out_of_bounds instead clang push address of that index 15 movl $10, -32(%ebp) 16 movl -28(%ebp), %eax 17 movl -32(%ebp), %ecx 18 movl %ecx, %edx 19 cmpl $10, %edx 20 movl %eax, -44(%ebp) # 4-byte Spill 21 movl %ecx, -48(%ebp) # 4-byte Spill 22 jb .LBB0_2 23 # BB#1: 24 leal .L__unnamed_1, %eax 25 leal -40(%ebp), %ecx 26 movl -48(%ebp), %edx # 4-byte Reload 27 movl %edx, -40(%ebp) 28 movl -44(%ebp), %esi # 4-byte Reload 29 movl %esi, -36(%ebp) 30 movl %eax, (%esp) 31 movl %ecx, 4(%esp) 32 calll __ubsan_handle_out_of_bounds In this case fix should be in IR generation for __ubsan_handle_out_of_bounds. Looks like tree val should be generated from original tree index and not from tree index which were converted to bound type. diff --git a/gcc/ubsan.c b/gcc/ubsan.c index 17965ef..c56f376 100644 --- a/gcc/ubsan.c +++ b/gcc/ubsan.c @@ -672,7 +672,8 @@ ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi) /* Pick up the arguments of the UBSAN_BOUNDS call. */ tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 0))); - tree index = gimple_call_arg (stmt, 1); + tree index, orig_index; + index = orig_index = gimple_call_arg (stmt, 1); tree orig_index_type = TREE_TYPE (index); tree bound = gimple_call_arg (stmt, 2); @@ -708,9 +709,9 @@ ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi) ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT; tree fn = builtin_decl_explicit (bcode); - tree val = force_gimple_operand_gsi (gsi, ubsan_encode_value (index), - true, NULL_TREE, true, - GSI_SAME_STMT); + tree val + = force_gimple_operand_gsi (gsi, ubsan_encode_value (orig_index), true, + NULL_TREE, true, GSI_SAME_STMT); g = gimple_build_call (fn, 2, data, val); } gimple_set_location (g, loc); I attached patch. Tests with make check RUNTESTFLAGS="ubsan.exp" passed for x86 32bit and 64 bit host.