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.