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
{