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.

Reply via email to