https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89014
Bug ID: 89014 Summary: Use-after-free in aarch64 -march=native Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: driver Assignee: unassigned at gcc dot gnu.org Reporter: dmalcolm at gcc dot gnu.org Target Milestone: --- Host: aarch64 Target: aarch64 This downstream report: https://bugzilla.redhat.com/show_bug.cgi?id=1668631 describes a problem with -march=native on aarch64 with a pre-release of gcc 9 (9.0.0-0.4.fc30.aarch64). /usr/bin/c++ -DHAVE_NLOHMANN_JSON -I/builddir/build/BUILD/xtl-0.5.3/include -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -fasynchronous-unwind-tables -fstack-clash-protection -DNDEBUG -Wunused-parameter -Wextra -Wreorder -Wconversion -Wsign-conversion -march=native -std=gnu++14 -o CMakeFiles/test_xcomplex_sequence.dir/test_xcomplex_sequence.cpp.o -c /builddir/build/BUILD/xtl-0.5.3/test/test_xcomplex_sequence.cpp Assembler messages: Error: unknown architecture `armv8-a�^&' Error: unrecognized option -march=armv8-a�^& cc1plus: error: unknown value 'armv8-\xf0^\x17' for -march cc1plus: note: valid arguments are: armv8-a armv8.1-a armv8.2-a armv8.3-a armv8.4-a armv8.5-a native; did you mean 'armv8-a'? Note the apparent data-corruption in the error message. This code in driver-aarch64.c looks suspicious to me: 351 ext_string 352 = aarch64_get_extension_string_for_isa_flags (extension_flags, 353 default_flags).c_str (); 354 355 res = concat (res, ext_string, NULL); as the std::string returned by aarch64_get_extension_string_for_isa_flags only lives until after the call to c_str, and thus is destroyed, and so the buffer pointed to by const char *ext_string has become invalid at line 355. I wasn't able to reproduce the precise corruption from the above report, but running the driver under valgrind shows: ==1326== Invalid read of size 1 ==1326== at 0x485A784: strlen (vg_replace_strmem.c:461) ==1326== by 0x48940F: vconcat_length (concat.c:65) ==1326== by 0x48940F: concat (concat.c:147) ==1326== by 0x414383: host_detect_local_cpu(int, char const**) (driver-aarch64.c:355) ==1326== by 0x40EAEB: eval_spec_function (gcc.c:6147) ==1326== by 0x40EAEB: handle_spec_function(char const*, bool*, char const*) (gcc.c:6228) ==1326== by 0x40D333: do_spec_1(char const*, int, char const*) (gcc.c:5928) ==1326== by 0x40F61F: process_brace_body (gcc.c:6596) ==1326== by 0x40F61F: handle_braces(char const*) (gcc.c:6503) ==1326== by 0x40D9EB: do_spec_1(char const*, int, char const*) (gcc.c:5922) ==1326== by 0x40E573: do_spec_2(char const*, char const*) (gcc.c:5024) ==1326== by 0x40FA5B: do_self_spec(char const*) (gcc.c:5088) ==1326== by 0x412B17: driver::set_up_specs() const (gcc.c:7599) ==1326== by 0x403FAF: driver::main(int, char**) (gcc.c:7357) ==1326== by 0x404203: main (gcc-main.c:47) ==1326== Address 0x4b09fc0 is 0 bytes inside a block of size 61 free'd ==1326== at 0x48588D0: operator delete(void*) (vg_replace_malloc.c:586) ==1326== by 0x414373: deallocate (new_allocator.h:125) ==1326== by 0x414373: deallocate (alloc_traits.h:462) ==1326== by 0x414373: _M_destroy (basic_string.h:226) ==1326== by 0x414373: _M_dispose (basic_string.h:221) ==1326== by 0x414373: ~basic_string (basic_string.h:657) ==1326== by 0x414373: host_detect_local_cpu(int, char const**) (driver-aarch64.c:352) ==1326== by 0x40EAEB: eval_spec_function (gcc.c:6147) ==1326== by 0x40EAEB: handle_spec_function(char const*, bool*, char const*) (gcc.c:6228) ==1326== by 0x40D333: do_spec_1(char const*, int, char const*) (gcc.c:5928) ==1326== by 0x40F61F: process_brace_body (gcc.c:6596) ==1326== by 0x40F61F: handle_braces(char const*) (gcc.c:6503) ==1326== by 0x40D9EB: do_spec_1(char const*, int, char const*) (gcc.c:5922) ==1326== by 0x40E573: do_spec_2(char const*, char const*) (gcc.c:5024) ==1326== by 0x40FA5B: do_self_spec(char const*) (gcc.c:5088) ==1326== by 0x412B17: driver::set_up_specs() const (gcc.c:7599) ==1326== by 0x403FAF: driver::main(int, char**) (gcc.c:7357) ==1326== by 0x404203: main (gcc-main.c:47) ==1326== Block was alloc'd at ==1326== at 0x48577B0: operator new(unsigned long) (vg_replace_malloc.c:344) ==1326== by 0x48E1C7: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_mutate(unsigned long, unsigned long, char const*, unsigned long) (in /home/dmalcolm/gcc-git-bugfixing/build/gcc/xgcc) ==1326== by 0x48FA47: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_append(char const*, unsigned long) (in /home/dmalcolm/gcc-git-bugfixing/build/gcc/xgcc) ==1326== by 0x414E27: append (basic_string.h:1268) ==1326== by 0x414E27: operator+= (basic_string.h:1178) ==1326== by 0x414E27: aarch64_get_extension_string_for_isa_flags[abi:cxx11](unsigned long, unsigned long) (aarch64-common.c:323) ==1326== by 0x41435B: host_detect_local_cpu(int, char const**) (driver-aarch64.c:352) ==1326== by 0x40EAEB: eval_spec_function (gcc.c:6147) ==1326== by 0x40EAEB: handle_spec_function(char const*, bool*, char const*) (gcc.c:6228) ==1326== by 0x40D333: do_spec_1(char const*, int, char const*) (gcc.c:5928) ==1326== by 0x40F61F: process_brace_body (gcc.c:6596) ==1326== by 0x40F61F: handle_braces(char const*) (gcc.c:6503) ==1326== by 0x40D9EB: do_spec_1(char const*, int, char const*) (gcc.c:5922) ==1326== by 0x40E573: do_spec_2(char const*, char const*) (gcc.c:5024) ==1326== by 0x40FA5B: do_self_spec(char const*) (gcc.c:5088) ==1326== by 0x412B17: driver::set_up_specs() const (gcc.c:7599) ..and with "-v" that, on my test box, the "-march" value passed by the driver to cc1 can be corrupt, or truncated. Am testing a fix.