https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71480
Bug ID: 71480 Summary: ASan should align string constants to shadow granularity. Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: sanitizer Assignee: unassigned at gcc dot gnu.org Reporter: m.ostapenko at samsung dot com CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org, jakub at gcc dot gnu.org, kcc at gcc dot gnu.org Target Milestone: --- Host: x86_64-pc-linux-gnu Target: arm-linux-gnueabi Consider following testcase: #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <stdlib.h> #include <stddef.h> #include <memory.h> #include <string.h> #include <strings.h> #include <inttypes.h> #include <stdint.h> #include <unistd.h> #include <ctype.h> #include <stdbool.h> #include <stdarg.h> int main (void) { struct stat st; char tpl[20] = "/tmp/test.XXXXXX"; char tpl2[20] = "/tmp/test.XXXXXX"; int fd = mkstemp (tpl); int fd2 = mkstemp (tpl2); if (fd == -1) { if (fd2 != -1) unlink (tpl2); exit (1); } if (fd2 == -1) exit (1); unlink (tpl); unlink (tpl2); if (fstat (fd, &st) != 0) exit(1); if ((st.st_mode & 0777) != 0600) exit (1); if (strcmp (tpl, "/tmp/test.XXXXXX") == 0) exit(1); if (strcmp (tpl, tpl2) == 0) exit(1); return 0; } When compiling this code to arm-linux-gnueabi with Thumb mode, "/tmp/test.XXXXXX" may actually stay unaligned to shadow granularity: $ armv7l-tizen-linux-gnueabi-gcc -O2 -mthumb test.c -S -fno-omit-frame-pointer $ cat test.s .section .rodata .align 2 .set .LANCHOR0,. + 0 .LC4: .ascii "/tmp/test.XXXXXX\000" .space 3 .space 44 .data .align 2 .set .LANCHOR1,. + 0 .type .LASAN0, %object .size .LASAN0, 28 .LASAN0: .word .LC4 .word 20 .word 64 .word .LC6 .word .LC7 .word 0 .word 0 .space 36 .section .rodata.str1.4,"aMS",%progbits,1 .align 2 Here, we have align == 2 for .LC4, that may cause runtime failure in ASan with something like this: bash-3.2# ASAN_OPTIONS=report_globals=2 /home/abuild/rpmbuild/BUILD/tdb-1.3.1/testprog #0 0x40859645 in __asan_register_globals (/usr/lib/libasan.so+0x25645) #1 0x10b67 in __libc_csu_init (/home/abuild/rpmbuild/BUILD/tdb-1.3.1/testprog+0x10b67) #2 0x40dd848b in __libc_start_main (/lib/libc.so.6+0x1648b) === ID 92274689; 0x00020dd0 0x00020dd0 ==8205==Added Global[0x00020dd0]: beg=0x00010b8c size=20/64 name=*.LC4 module=test.c dyn_init=0 ==8205==AddressSanitizer CHECK failed: ../../../../libsanitizer/asan/asan_globals.cc:145 "((AddrIsAlignedByGranularity(g->beg))) != (0)" (0x0, 0x0) #0 0x408cd749 (/usr/lib/libasan.so+0x99749) #1 0x408d1e5d in __sanitizer::CheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) (/usr/lib/libasan.so+0x9de5d) #2 0x40859a1f in __asan_register_globals (/usr/lib/libasan.so+0x25a1f) #3 0x10b67 in __libc_csu_init (/home/abuild/rpmbuild/BUILD/tdb-1.3.1/testprog+0x10b67) #4 0x40dd848b in __libc_start_main (/lib/libc.so.6+0x1648b) The problem here is that for ".LC4" TREE_CONSTANT_POOL_ADDRESS_P (symbol) is true and we don't enforce additional alignment requirements in place_block_symbol. Perhaps something like this can fix the issue: diff --git a/gcc/varasm.c b/gcc/varasm.c index 4a7124e..de8bcd6 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -7201,7 +7201,11 @@ place_block_symbol (rtx symbol) if ((flag_sanitize & SANITIZE_ADDRESS) && TREE_CODE (DECL_INITIAL (decl)) == STRING_CST && asan_protect_global (DECL_INITIAL (decl))) - size += asan_red_zone_size (size); + { + size += asan_red_zone_size (size); + alignment = MAX (alignment, + ASAN_RED_ZONE_SIZE * BITS_PER_UNIT); + } } else {