[Bug fortran/96381] New: gfc_find_vtab can use a character type typespec as a derived type (causing invalid access)
matmal01 at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Wed Jul 29 16:56:26 GMT 2020
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96381
Bug ID: 96381
Summary: gfc_find_vtab can use a character type typespec as a
derived type (causing invalid access)
Product: gcc
Version: 11.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: fortran
Assignee: unassigned at gcc dot gnu.org
Reporter: matmal01 at gcc dot gnu.org
Target Milestone: ---
When running the testsuite with a compiler sanitized with -fsanitize=hwaddress
(HWASAN sanitizer which is not yet committed upstream) I saw the error below.
The error comes from the testsuite running `pr93337.f90`.
It is complaining that `gfc_find_derived_vtab` is attempting to access an 8
byte chunk of data 88 bytes after a region that is only 48 bytes long.
That seems to be coming from the access of `derived->attr.pdt_template` (which
is a one-bit field in the byte 92 bytes into a `gfc_symbol` structure).
According to the dump the 48 byte long structure is allocated in
`gfc_new_charlen`.
This function only ever sets the `cl` alternative of the union in a
`gfc_typespec`.
I've inlined a GDB session demonstrating the mis-use under the HWASAN dump.
==25394==ERROR: HWAddressSanitizer: tag-mismatch on address 0xefdfffff79d8 at
pc 0x0000006a8560
READ of size 8 at 0xefdfffff79d8 tags: 58/ff (ptr/mem) in thread T0
#0 0x6a855c in SigTrap<3>
../../../../gcc-source/libsanitizer/hwasan/hwasan_checks.h:27
#1 0x6a855c in CheckAddress<(__hwasan::ErrorAction)0,
(__hwasan::AccessType)0, 3>
../../../../gcc-source/libsanitizer/hwasan/hwasan_checks.h:88
#2 0x6a855c in __hwasan_load8
../../../../gcc-source/libsanitizer/hwasan/hwasan.cpp:454
#3 0x6ff654 in gfc_find_derived_vtab(gfc_symbol*)
../../gcc-source/gcc/fortran/class.c:2269
#4 0x707498 in gfc_find_vtab(gfc_typespec*)
../../gcc-source/gcc/fortran/class.c:2908
#5 0x707498 in gfc_find_vtab(gfc_typespec*)
../../gcc-source/gcc/fortran/class.c:2898
#6 0x7a7578 in gfc_match_assignment()
../../gcc-source/gcc/fortran/match.c:1393
#7 0x80d53c in match_word ../../gcc-source/gcc/fortran/parse.c:65
#8 0x80d53c in decode_statement ../../gcc-source/gcc/fortran/parse.c:361
#9 0x812f28 in next_free ../../gcc-source/gcc/fortran/parse.c:1280
#10 0x812f28 in next_statement ../../gcc-source/gcc/fortran/parse.c:1512
#11 0x816190 in parse_spec ../../gcc-source/gcc/fortran/parse.c:3923
#12 0x819948 in parse_progunit ../../gcc-source/gcc/fortran/parse.c:5853
#13 0x81c02c in gfc_parse_file() ../../gcc-source/gcc/fortran/parse.c:6394
#14 0x898d98 in gfc_be_parse_file
../../gcc-source/gcc/fortran/f95-lang.c:212
#15 0x152ac7c in compile_file ../../gcc-source/gcc/toplev.c:458
#16 0x69d114 in do_compile ../../gcc-source/gcc/toplev.c:2320
#17 0x69d114 in toplev::main(int, char**)
../../gcc-source/gcc/toplev.c:2459
#18 0x6a0218 in main ../../gcc-source/gcc/main.c:39
#19 0xffffa03c38dc in __libc_start_main
(/lib/aarch64-linux-gnu/libc.so.6+0x1f8dc)
[0xefdfffff79c0,0xefdfffff7a00) is a small allocated heap chunk; size: 64
offset: 24
0xefdfffff79d8 is located 40 bytes to the right of 48-byte region
[0xefdfffff7980,0xefdfffff79b0)
allocated here:
#0 0x6a9d40 in __sanitizer_calloc
../../../../gcc-source/libsanitizer/hwasan/hwasan_interceptors.cpp:138
#1 0x2d1ebbc in xcalloc ../../gcc-source/libiberty/xmalloc.c:162
#2 0x8831a0 in gfc_new_charlen(gfc_namespace*, gfc_charlen*)
../../gcc-source/gcc/fortran/symbol.c:3964
#3 0x7146ec in gfc_match_char_spec(gfc_typespec*)
../../gcc-source/gcc/fortran/decl.c:3478
#4 0x71e324 in gfc_match_decl_type_spec(gfc_typespec*, int)
../../gcc-source/gcc/fortran/decl.c:4169
#5 0x7220d8 in gfc_match_data_decl()
../../gcc-source/gcc/fortran/decl.c:6129
#6 0x80d6b0 in match_word ../../gcc-source/gcc/fortran/parse.c:65
#7 0x80d6b0 in decode_statement ../../gcc-source/gcc/fortran/parse.c:376
#8 0x812f28 in next_free ../../gcc-source/gcc/fortran/parse.c:1280
#9 0x812f28 in next_statement ../../gcc-source/gcc/fortran/parse.c:1512
#10 0x816600 in parse_derived ../../gcc-source/gcc/fortran/parse.c:3343
#11 0x816600 in parse_spec ../../gcc-source/gcc/fortran/parse.c:3884
#12 0x819948 in parse_progunit ../../gcc-source/gcc/fortran/parse.c:5853
#13 0x81c02c in gfc_parse_file() ../../gcc-source/gcc/fortran/parse.c:6394
#14 0x898d98 in gfc_be_parse_file
../../gcc-source/gcc/fortran/f95-lang.c:212
#15 0x152ac7c in compile_file ../../gcc-source/gcc/toplev.c:458
#16 0x69d114 in do_compile ../../gcc-source/gcc/toplev.c:2320
#17 0x69d114 in toplev::main(int, char**)
../../gcc-source/gcc/toplev.c:2459
#18 0x6a0218 in main ../../gcc-source/gcc/main.c:39
#19 0xffffa03c38dc in __libc_start_main
(/lib/aarch64-linux-gnu/libc.so.6+0x1f8dc)
#20 0x6a3e5c
(/home/ubuntu/working-directory/gcc-hwasan-install/libexec/gcc/aarch64-unknown-linux-gnu/11.0.0/f951+0x6a3e5c)
Thread: T0 0xeffe00002000 stack: [0xfffffabad000,0xfffffebad000) sz: 67108864
tls: [0xffffa060b000,0xffffa060b850)
Memory tags around the buggy address (one tag corresponds to 16 bytes):
0xfefcfffff710: b5 b5 b5 08 1a 1a 1a 1a 47 47 47 08 2b 2b 2b
08
0xfefcfffff720: 79 79 79 08 ad ad ad ad 77 77 77 08 42 42 42
08
0xfefcfffff730: 70 70 70 70 93 93 93 08 36 36 36 36 19 19 19
08
0xfefcfffff740: 6e 6e 6e 6e c2 c2 c2 08 29 29 29 08 9f 9f 9f
9f
0xfefcfffff750: ce ce ce 08 3c 3c 3c ed d1 d1 d1 08 2a 2a 2a
08
0xfefcfffff760: bb bb bb bb e9 e9 e9 08 2c 2c 2c 08 b4 b4 b4
b4
0xfefcfffff770: 33 33 33 08 0d 0d 0d 08 ec ec ec ec 29 29 29
08
0xfefcfffff780: bf bf bf 08 f9 f9 f9 f9 f0 f0 f0 08 01 01 01
08
=>0xfefcfffff790: fc fc fc fc f0 f0 f0 08 58 58 58 81 ff [ff] ff
08
0xfefcfffff7a0: a8 a8 a8 08 83 83 83 83 f3 f3 f3 08 9e 9e 9e
08
0xfefcfffff7b0: bf bf bf 08 7f 7f 7f 7f cc cc 04 9e 43 43 43
43
0xfefcfffff7c0: c4 c4 c4 c4 12 12 12 b5 36 36 36 36 2d 2d 2d
2d
0xfefcfffff7d0: 65 65 65 65 cc cc cc cc 4c 4c 4c 4c 78 78 78
0e
0xfefcfffff7e0: d1 d1 d1 d1 f5 f5 f5 f5 57 57 57 08 b0 b0 b0
08
0xfefcfffff7f0: 5e 5e 5e 08 49 49 49 08 7c 7c 7c 08 85 85 85
08
0xfefcfffff800: 63 63 63 08 7d 7d 7d 08 0d 0d 0d 08 71 71 71
08
0xfefcfffff810: 06 06 08 97 74 74 74 08 bb bb bb 08 aa aa aa
08
Tags for short granules around the buggy address (one tag corresponds to 16
bytes):
0xfefcfffff780: .. .. .. bf .. .. .. .. .. .. .. f0 f0 00 00
01
=>0xfefcfffff790: .. .. .. .. .. .. .. f0 .. .. .. .. .. [..] ..
ff
0xfefcfffff7a0: .. .. .. a8 .. .. .. .. .. .. .. f3 .. .. ..
9e
See
https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html#short-granules
for a description of short granule tags
SUMMARY: HWAddressSanitizer: tag-mismatch
../../../../gcc-source/libsanitizer/hwasan/hwasan_checks.h:27 in SigTrap<3>
GDB session demonstrating this happening (to demonstrate that this does seem to
be misusing a `gfc_charlen*` as a `gfc_symbol *`).
ubuntu@ubuntu:~/working-directory$ ./gcc-hwasan-install/bin/gfortran
gcc-source/gcc/testsuite/gfortran.dg/pr93337.f90 -O -pedantic-errors -S -o -
-wrapper gdb,-q,--args
Reading symbols from
/home/ubuntu/working-directory/gcc-hwasan-install/libexec/gcc/aarch64-unknown-linux-gnu/11.0.0/f951...done.
(gdb) break decl.c:3516 if $_any_caller_is("gfc_match_decl_type_spec")
Breakpoint 1 at 0x714814: file ../../gcc-source/gcc/fortran/decl.c, line 3516.
(gdb) run
Starting program:
/home/ubuntu/working-directory/gcc-hwasan-install/libexec/gcc/aarch64-unknown-linux-gnu/11.0.0/f951
gcc-source/gcc/testsuite/gfortran.dg/pr93337.f90 -quiet -dumpbase pr93337.f90
-dumpbase-ext .f90 -mlittle-endian -mabi=lp64 -O -pedantic-errors -o -
-fintrinsic-modules-path
/home/ubuntu/working-directory/gcc-hwasan-install/lib/gcc/aarch64-unknown-linux-gnu/11.0.0/finclude
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/aarch64-linux-gnu/libthread_db.so.1".
.arch armv8-a
.file "pr93337.f90"
Breakpoint 1, gfc_match_char_spec (ts=ts@entry=0x4028c58 <current_ts>) at
../../gcc-source/gcc/fortran/decl.c:3516
3516 ts->u.cl = cl;
(gdb) print cl
$1 = (gfc_charlen *) 0x3100efdfffff3440
(gdb) break gfc_find_derived_vtab if (void*)derived == (void*)$1
Breakpoint 2 at 0x6ff370: file ../../gcc-source/gcc/fortran/class.c, line 2262.
(gdb) cont
Continuing.
Breakpoint 2, gfc_find_derived_vtab (derived=derived@entry=0x3100efdfffff3440)
at ../../gcc-source/gcc/fortran/class.c:2262
2262 {
(gdb)
More information about the Gcc-bugs
mailing list