https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125723

            Bug ID: 125723
           Summary: heap-use-after-free in
                    cpp_display_width_computation::process_next_codepoint
                    when line marker file is 2^n * 8192 bytes
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: daniel.wait.dev at gmail dot com
  Target Milestone: ---
              Host: x86_64-pc-linux-gnu
            Target: x86_64-pc-linux-gnu
             Build: x86_64-pc-linux-gnu

Heap-use-after-free while producing the diagnostic for a parsing error on an
invalid preprocessed C input with an ASan-enabled GCC build.

This occurs when a preprocessed file, source.i, references another file via a
line marker and then contains invalid C.

The referenced line marker file, source.c, must have size 2^n * 8192 bytes,
where n = 0, 1, 2, 3, etc. For example, I can reproduce this with source.c
sizes: 8192, 16384, 32768, 65536.

The contents of source.c do not appear to matter. It is sufficient to create a
file of the required size with truncate.

GCC version 17.0.0
Commit b700707a77eeaa1d37f733c4b2d2e242063c29d2
System type x86_64-pc-linux-gnu

Configured with:
../gcc-latest/configure CFLAGS='-O2 -g' CXXFLAGS='-O2 -g' --enable-languages=c
--enable-checking=yes --enable-bootstrap --with-build-config=bootstrap-asan
--disable-multilib --disable-nls --disable-lto --disable-libgomp
--disable-libquadmath --disable-libssp

Reproduction steps:

$ cat > source.i <<EOF
# 1 "source.c"
x
EOF

$ truncate -s 8192 source.c

$ ASAN_OPTIONS=detect_leaks=0 ./gcc-latest-asan/gcc/xgcc
-B./gcc-latest-asan/gcc source.i
=================================================================
==588196==ERROR: AddressSanitizer: heap-use-after-free on address
0x709a001ec900 at pc 0x00000758b06f bp 0x7fffe072e960 sp 0x7fffe072e958
READ of size 1 at 0x709a001ec900 thread T0
    #0 0x00000758b06e in
cpp_display_width_computation::process_next_codepoint(cpp_decoded_char*)
../../gcc-latest/libcpp/charset.cc:3413
    #1 0x00000758b06e in cpp_byte_column_to_display_column(char const*, int,
int, cpp_char_column_policy const&) ../../gcc-latest/libcpp/charset.cc:3484
    #2 0x0000074638d0 in
location_compute_display_column(diagnostics::file_cache&, expanded_location,
cpp_char_column_policy const&) ../../gcc-latest/gcc/input.cc:377
    #3 0x0000071f7e86 in convert_column_unit
../../gcc-latest/gcc/diagnostics/context.cc:778
    #4 0x0000071f7e86 in
diagnostics::column_options::convert_column(diagnostics::file_cache&,
expanded_location) const ../../gcc-latest/gcc/diagnostics/context.cc:793
    #5 0x0000071f8188 in
diagnostics::column_policy::converted_column(expanded_location) const
../../gcc-latest/gcc/diagnostics/context.cc:811
    #6 0x0000071f8188 in
diagnostics::column_policy::get_location_text(expanded_location const&, bool,
bool) const ../../gcc-latest/gcc/diagnostics/context.cc:830
    #7 0x0000072e1f32 in
diagnostics::text_sink::get_location_text(expanded_location const&) const
../../gcc-latest/gcc/diagnostics/text-sink.cc:608
    #8 0x0000072e1f32 in
diagnostics::text_sink::build_prefix(diagnostics::diagnostic_info const&) const
../../gcc-latest/gcc/diagnostics/text-sink.cc:331
    #9 0x000002b0f485 in default_tree_diagnostic_text_starter
../../gcc-latest/gcc/tree-diagnostic.cc:55
    #10 0x0000072e1359 in
diagnostics::text_sink::on_report_diagnostic(diagnostics::diagnostic_info
const&, diagnostics::kind) ../../gcc-latest/gcc/diagnostics/text-sink.cc:215
    #11 0x0000071fd29b in
diagnostics::context::report_diagnostic(diagnostics::diagnostic_info*)
../../gcc-latest/gcc/diagnostics/context.cc:1535
    #12 0x0000071fed50 in diagnostics::context::diagnostic_impl(rich_location*,
diagnostics::metadata const*, diagnostics::option_id, char const*,
__va_list_tag (*) [1], diagnostics::kind)
../../gcc-latest/gcc/diagnostics/context.cc:1689
    #13 0x0000071d487e in error_at(rich_location*, char const*, ...)
../../gcc-latest/gcc/diagnostic-global-context.cc:676
    #14 0x0000010c7b63 in c_parse_error(char const*, cpp_ttype, tree_node*,
unsigned char, rich_location*) ../../gcc-latest/gcc/c-family/c-common.cc:7096
    #15 0x000000ecf55a in c_parser_error_richloc
../../gcc-latest/gcc/c/c-parser.cc:1117
    #16 0x000000ed26c8 in c_parser_error(c_parser*, char const*)
../../gcc-latest/gcc/c/c-parser.cc:1140
    #17 0x000000fa91c1 in c_parser_declaration_or_fndef
../../gcc-latest/gcc/c/c-parser.cc:3268
    #18 0x000001005161 in c_parser_external_declaration
../../gcc-latest/gcc/c/c-parser.cc:2256
    #19 0x00000100808f in c_parser_translation_unit
../../gcc-latest/gcc/c/c-parser.cc:2095
    #20 0x00000100808f in c_parse_file()
../../gcc-latest/gcc/c/c-parser.cc:31480
    #21 0x00000118e392 in c_common_parse_file()
../../gcc-latest/gcc/c-family/c-opts.cc:1430
    #22 0x000002990bad in compile_file ../../gcc-latest/gcc/toplev.cc:455
    #23 0x000000be1180 in do_compile ../../gcc-latest/gcc/toplev.cc:2228
    #24 0x000000be1180 in toplev::main(int, char**)
../../gcc-latest/gcc/toplev.cc:2392
    #25 0x000000bed450 in main ../../gcc-latest/gcc/main.cc:39
    #26 0x724a00e471c9  (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId:
8e9fd827446c24067541ac5390e6f527fb5947bb)
    #27 0x724a00e4728a in __libc_start_main
(/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId:
8e9fd827446c24067541ac5390e6f527fb5947bb)
    #28 0x000000c0b6b4 in _start
(/workspaces/fyp/new/sut/gcc-latest-asan/gcc/cc1+0xc0b6b4)

0x709a001ec900 is located 0 bytes inside of 8192-byte region
[0x709a001ec900,0x709a001ee900)
freed by thread T0 here:
    #0 0x000000cf439f in realloc
../../../../gcc-latest/libsanitizer/asan/asan_malloc_linux.cpp:81
    #1 0x0000076d0ad0 in xrealloc ../../gcc-latest/libiberty/xmalloc.c:181

previously allocated by thread T0 here:
    #0 0x000000cf439f in realloc
../../../../gcc-latest/libsanitizer/asan/asan_malloc_linux.cpp:81
    #1 0x0000076d0ad0 in xrealloc ../../gcc-latest/libiberty/xmalloc.c:181

SUMMARY: AddressSanitizer: heap-use-after-free
../../gcc-latest/libcpp/charset.cc:3413 in
cpp_display_width_computation::process_next_codepoint(cpp_decoded_char*)
Shadow bytes around the buggy address:
  0x709a001ec680: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x709a001ec700: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x709a001ec780: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x709a001ec800: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x709a001ec880: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x709a001ec900:[fd]fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x709a001ec980: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x709a001eca00: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x709a001eca80: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x709a001ecb00: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x709a001ecb80: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==588196==ABORTING

Reply via email to