Bug 100311 - UB in sel-sched.c:init_regs_for_mode with -march=armv8-m.base
Summary: UB in sel-sched.c:init_regs_for_mode with -march=armv8-m.base
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 12.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks: ubsan
  Show dependency treegraph
 
Reported: 2021-04-28 08:37 UTC by Alex Coplan
Modified: 2021-04-29 10:57 UTC (History)
1 user (show)

See Also:
Host:
Target: arm-eabi
Build:
Known to work:
Known to fail: 12.0
Last reconfirmed: 2021-04-28 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Alex Coplan 2021-04-28 08:37:17 UTC
For the following testcase on arm:

int a;
long long b;
long long c() { return a + b; }

building GCC with -fsanitize=undefined and invoking as:

./arm-eabi-gcc -c test.c -march=armv8-m.base -O2 -fselective-scheduling2

shows the following problems:

/data_sdb/toolchain/src/gcc/gcc/sel-sched.c:1080:35: runtime error: index 107 out of bounds for type 'char [107]'
    #0 0x1bad6bc in init_regs_for_mode /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:1080
    #1 0x1bad6bc in mark_unavailable_hard_regs /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:1242
    #2 0x1bad6bc in find_used_regs /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:3295
    #3 0x1bad6bc in collect_unavailable_regs_from_bnds /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:1586
    #4 0x1bad6bc in find_best_reg_for_expr /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:1649
    #5 0x1bad6bc in fill_vec_av_set /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:3784
    #6 0x1bb8174 in fill_ready_list /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:4014
    #7 0x1bb8174 in find_best_expr /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:4374
    #8 0x1bb8174 in fill_insns /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:5535
    #9 0x1bb8174 in schedule_on_fences /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:7353
    #10 0x1bb8174 in sel_sched_region_2 /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:7491
    #11 0x1bc2b30 in sel_sched_region_1 /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:7533
    #12 0x1bc4beb in sel_sched_region(int) /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:7634
    #13 0x1bc966d in run_selective_scheduling() /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:7720
    #14 0x1b3881c in rest_of_handle_sched2 /data_sdb/toolchain/src/gcc/gcc/sched-rgn.c:3738
    #15 0x1b3881c in execute /data_sdb/toolchain/src/gcc/gcc/sched-rgn.c:3882
    #16 0x1925050 in execute_one_pass(opt_pass*) /data_sdb/toolchain/src/gcc/gcc/passes.c:2567
    #17 0x1927afc in execute_pass_list_1 /data_sdb/toolchain/src/gcc/gcc/passes.c:2656
    #18 0x1927aba in execute_pass_list_1 /data_sdb/toolchain/src/gcc/gcc/passes.c:2657
    #19 0x1927aba in execute_pass_list_1 /data_sdb/toolchain/src/gcc/gcc/passes.c:2657
    #20 0x1927b57 in execute_pass_list(function*, opt_pass*) /data_sdb/toolchain/src/gcc/gcc/passes.c:2667
    #21 0xc22722 in cgraph_node::expand() /data_sdb/toolchain/src/gcc/gcc/cgraphunit.c:1828
    #22 0xc28a02 in expand_all_functions /data_sdb/toolchain/src/gcc/gcc/cgraphunit.c:1992
    #23 0xc28a02 in symbol_table::compile() /data_sdb/toolchain/src/gcc/gcc/cgraphunit.c:2356
    #24 0xc33b18 in symbol_table::finalize_compilation_unit() /data_sdb/toolchain/src/gcc/gcc/cgraphunit.c:2537
    #25 0x1cc9ceb in compile_file /data_sdb/toolchain/src/gcc/gcc/toplev.c:482
    #26 0x1cd062b in do_compile /data_sdb/toolchain/src/gcc/gcc/toplev.c:2201
    #27 0x1cd062b in toplev::main(int, char**) /data_sdb/toolchain/src/gcc/gcc/toplev.c:2340
    #28 0x43146ce in main /data_sdb/toolchain/src/gcc/gcc/main.c:39
    #29 0x7ffff6740bf6 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21bf6)
    #30 0x645bc9 in _start (/data_sdb/toolchain/build-arm-eabi-armv8-m.base/install/libexec/gcc/arm-eabi/12.0.0/cc1+0x645bc9)

/data_sdb/toolchain/src/gcc/gcc/sel-sched.c:1081:43: runtime error: index 107 out of bounds for type 'char [107]'
    #0 0x1bad6e0 in init_regs_for_mode /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:1081
    #1 0x1bad6e0 in mark_unavailable_hard_regs /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:1242
    #2 0x1bad6e0 in find_used_regs /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:3295
    #3 0x1bad6e0 in collect_unavailable_regs_from_bnds /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:1586
    #4 0x1bad6e0 in find_best_reg_for_expr /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:1649
    #5 0x1bad6e0 in fill_vec_av_set /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:3784
    #6 0x1bb8174 in fill_ready_list /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:4014
    #7 0x1bb8174 in find_best_expr /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:4374
    #8 0x1bb8174 in fill_insns /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:5535
    #9 0x1bb8174 in schedule_on_fences /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:7353
    #10 0x1bb8174 in sel_sched_region_2 /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:7491
    #11 0x1bc2b30 in sel_sched_region_1 /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:7533
    #12 0x1bc4beb in sel_sched_region(int) /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:7634
    #13 0x1bc966d in run_selective_scheduling() /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:7720
    #14 0x1b3881c in rest_of_handle_sched2 /data_sdb/toolchain/src/gcc/gcc/sched-rgn.c:3738
    #15 0x1b3881c in execute /data_sdb/toolchain/src/gcc/gcc/sched-rgn.c:3882
    #16 0x1925050 in execute_one_pass(opt_pass*) /data_sdb/toolchain/src/gcc/gcc/passes.c:2567
    #17 0x1927afc in execute_pass_list_1 /data_sdb/toolchain/src/gcc/gcc/passes.c:2656
    #18 0x1927aba in execute_pass_list_1 /data_sdb/toolchain/src/gcc/gcc/passes.c:2657
    #19 0x1927aba in execute_pass_list_1 /data_sdb/toolchain/src/gcc/gcc/passes.c:2657
    #20 0x1927b57 in execute_pass_list(function*, opt_pass*) /data_sdb/toolchain/src/gcc/gcc/passes.c:2667
    #21 0xc22722 in cgraph_node::expand() /data_sdb/toolchain/src/gcc/gcc/cgraphunit.c:1828
    #22 0xc28a02 in expand_all_functions /data_sdb/toolchain/src/gcc/gcc/cgraphunit.c:1992
    #23 0xc28a02 in symbol_table::compile() /data_sdb/toolchain/src/gcc/gcc/cgraphunit.c:2356
    #24 0xc33b18 in symbol_table::finalize_compilation_unit() /data_sdb/toolchain/src/gcc/gcc/cgraphunit.c:2537
    #25 0x1cc9ceb in compile_file /data_sdb/toolchain/src/gcc/gcc/toplev.c:482
    #26 0x1cd062b in do_compile /data_sdb/toolchain/src/gcc/gcc/toplev.c:2201
    #27 0x1cd062b in toplev::main(int, char**) /data_sdb/toolchain/src/gcc/gcc/toplev.c:2340
    #28 0x43146ce in main /data_sdb/toolchain/src/gcc/gcc/main.c:39
    #29 0x7ffff6740bf6 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21bf6)
    #30 0x645bc9 in _start (/data_sdb/toolchain/build-arm-eabi-armv8-m.base/install/libexec/gcc/arm-eabi/12.0.0/cc1+0x645bc9)

/data_sdb/toolchain/src/gcc/gcc/sel-sched.c:1081:43: runtime error: load of address 0x000009688beb with insufficient space for an object of type 'char'
0x000009688beb: note: pointer points here
 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 01 01 01 01 01
              ^
    #0 0x1bad6f8 in init_regs_for_mode /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:1081
    #1 0x1bad6f8 in mark_unavailable_hard_regs /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:1242
    #2 0x1bad6f8 in find_used_regs /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:3295
    #3 0x1bad6f8 in collect_unavailable_regs_from_bnds /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:1586
    #4 0x1bad6f8 in find_best_reg_for_expr /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:1649
    #5 0x1bad6f8 in fill_vec_av_set /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:3784
    #6 0x1bb8174 in fill_ready_list /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:4014
    #7 0x1bb8174 in find_best_expr /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:4374
    #8 0x1bb8174 in fill_insns /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:5535
    #9 0x1bb8174 in schedule_on_fences /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:7353
    #10 0x1bb8174 in sel_sched_region_2 /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:7491
    #11 0x1bc2b30 in sel_sched_region_1 /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:7533
    #12 0x1bc4beb in sel_sched_region(int) /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:7634
    #13 0x1bc966d in run_selective_scheduling() /data_sdb/toolchain/src/gcc/gcc/sel-sched.c:7720
    #14 0x1b3881c in rest_of_handle_sched2 /data_sdb/toolchain/src/gcc/gcc/sched-rgn.c:3738
    #15 0x1b3881c in execute /data_sdb/toolchain/src/gcc/gcc/sched-rgn.c:3882
    #16 0x1925050 in execute_one_pass(opt_pass*) /data_sdb/toolchain/src/gcc/gcc/passes.c:2567
    #17 0x1927afc in execute_pass_list_1 /data_sdb/toolchain/src/gcc/gcc/passes.c:2656
    #18 0x1927aba in execute_pass_list_1 /data_sdb/toolchain/src/gcc/gcc/passes.c:2657
    #19 0x1927aba in execute_pass_list_1 /data_sdb/toolchain/src/gcc/gcc/passes.c:2657
    #20 0x1927b57 in execute_pass_list(function*, opt_pass*) /data_sdb/toolchain/src/gcc/gcc/passes.c:2667
    #21 0xc22722 in cgraph_node::expand() /data_sdb/toolchain/src/gcc/gcc/cgraphunit.c:1828
    #22 0xc28a02 in expand_all_functions /data_sdb/toolchain/src/gcc/gcc/cgraphunit.c:1992
    #23 0xc28a02 in symbol_table::compile() /data_sdb/toolchain/src/gcc/gcc/cgraphunit.c:2356
    #24 0xc33b18 in symbol_table::finalize_compilation_unit() /data_sdb/toolchain/src/gcc/gcc/cgraphunit.c:2537
    #25 0x1cc9ceb in compile_file /data_sdb/toolchain/src/gcc/gcc/toplev.c:482
    #26 0x1cd062b in do_compile /data_sdb/toolchain/src/gcc/gcc/toplev.c:2201
    #27 0x1cd062b in toplev::main(int, char**) /data_sdb/toolchain/src/gcc/gcc/toplev.c:2340
    #28 0x43146ce in main /data_sdb/toolchain/src/gcc/gcc/main.c:39
    #29 0x7ffff6740bf6 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21bf6)
    #30 0x645bc9 in _start (/data_sdb/toolchain/build-arm-eabi-armv8-m.base/install/libexec/gcc/arm-eabi/12.0.0/cc1+0x645bc9)
Comment 1 Richard Earnshaw 2021-04-28 11:07:16 UTC
Suggested fix:
https://gcc.gnu.org/pipermail/gcc-patches/2021-April/569006.html
Comment 2 CVS Commits 2021-04-28 16:59:45 UTC
The master branch has been updated by Richard Earnshaw <rearnsha@gcc.gnu.org>:

https://gcc.gnu.org/g:59f5d16f2c5db4d9592c8ce6453afe81334bb012

commit r12-222-g59f5d16f2c5db4d9592c8ce6453afe81334bb012
Author: Richard Earnshaw <rearnsha@arm.com>
Date:   Wed Apr 28 17:56:38 2021 +0100

    arm: fix UB due to missing mode check [PR100311]
    
    Some places in the compiler iterate over all the fixed registers to
    check if that register can be used in a particular mode.  The idiom is
    to iterate over the register and then for that register, if it
    supports the current mode to check all that register and any
    additional registers needed (HARD_REGNO_NREGS).  If these two checks
    are not fully aligned then it is possible to generate a buffer overrun
    when testing data objects that are sized by the number of hard regs in
    the machine.
    
    The VPR register is a case where these checks were not consistent and
    because this is the last HARD register the result was that we ended up
    overflowing the fixed_regs array.
    
    gcc:
            PR target/100311
            * config/arm/arm.c (arm_hard_regno_mode_ok): Only allow VPR to be
            used in HImode.
Comment 3 CVS Commits 2021-04-29 10:56:35 UTC
The releases/gcc-11 branch has been updated by Richard Earnshaw <rearnsha@gcc.gnu.org>:

https://gcc.gnu.org/g:bda407c9a0da4aacdc62306c85712b93afa1bbc3

commit r11-8328-gbda407c9a0da4aacdc62306c85712b93afa1bbc3
Author: Richard Earnshaw <rearnsha@arm.com>
Date:   Wed Apr 28 17:56:38 2021 +0100

    arm: fix UB due to missing mode check [PR100311]
    
    Some places in the compiler iterate over all the fixed registers to
    check if that register can be used in a particular mode.  The idiom is
    to iterate over the register and then for that register, if it
    supports the current mode to check all that register and any
    additional registers needed (HARD_REGNO_NREGS).  If these two checks
    are not fully aligned then it is possible to generate a buffer overrun
    when testing data objects that are sized by the number of hard regs in
    the machine.
    
    The VPR register is a case where these checks were not consistent and
    because this is the last HARD register the result was that we ended up
    overflowing the fixed_regs array.
    
    gcc:
            PR target/100311
            * config/arm/arm.c (arm_hard_regno_mode_ok): Only allow VPR to be
            used in HImode.
    (cherry picked from commit 59f5d16f2c5db4d9592c8ce6453afe81334bb012)
Comment 4 CVS Commits 2021-04-29 10:56:52 UTC
The releases/gcc-10 branch has been updated by Richard Earnshaw <rearnsha@gcc.gnu.org>:

https://gcc.gnu.org/g:d0ae39ce2c3b4d635de6102ec3750cf6109cdc8d

commit r10-9778-gd0ae39ce2c3b4d635de6102ec3750cf6109cdc8d
Author: Richard Earnshaw <rearnsha@arm.com>
Date:   Wed Apr 28 17:56:38 2021 +0100

    arm: fix UB due to missing mode check [PR100311]
    
    Some places in the compiler iterate over all the fixed registers to
    check if that register can be used in a particular mode.  The idiom is
    to iterate over the register and then for that register, if it
    supports the current mode to check all that register and any
    additional registers needed (HARD_REGNO_NREGS).  If these two checks
    are not fully aligned then it is possible to generate a buffer overrun
    when testing data objects that are sized by the number of hard regs in
    the machine.
    
    The VPR register is a case where these checks were not consistent and
    because this is the last HARD register the result was that we ended up
    overflowing the fixed_regs array.
    
    gcc:
            PR target/100311
            * config/arm/arm.c (arm_hard_regno_mode_ok): Only allow VPR to be
            used in HImode.
    (cherry picked from commit 59f5d16f2c5db4d9592c8ce6453afe81334bb012)
Comment 5 Richard Earnshaw 2021-04-29 10:57:40 UTC
Fixed on all relevant branches.