Hi,

this patch (preapproved by Jakub in BZ) fixes an issue with insufficient (4 byte, should be at least 8) alignment of ASan protected string constants. I can reproduce this on arm-linux-gnueabi target, but this may affect powerpc* targets too, so I enabled the testcase for both arm and powerpc targets. The regexp in testcase may look messy, but it simply tries to match following line in asm dump:

        .section        .rodata
        .align  5
        .set    .LANCHOR*
.LC[0-9]:
        .ascii  "/tmp/test.XXXXXX\000"

Regtested on x86_64-unknown-linux-gnu and arm-linux-gnueabi (I didn't manage to test on PowerPC), ok for trunk?

-Maxim
gcc/ChangeLog:

2016-06-10  Maxim Ostapenko  <m.ostape...@samsung.com>

	PR sanitizer/71480
	* varasm.c (place_block_symbol): Adjust alignment for asan protected
	STRING_CSTs even if TREE_CONSTANT_POOL_ADDRESS_P.

gcc/testsuite/ChangeLog:

2016-06-10  Maxim Ostapenko  <m.ostape...@samsung.com>

	PR sanitizer/71480
	* c-c++-common/asan/pr71480.c: New test.

diff --git a/gcc/testsuite/c-c++-common/asan/pr71480.c b/gcc/testsuite/c-c++-common/asan/pr71480.c
new file mode 100644
index 0000000..cf08ec6
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/pr71480.c
@@ -0,0 +1,41 @@
+/* { dg-do compile { target { arm*-*-* powerpc*-*-linux* } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int
+strcmp(const char *s1, const char *s2);
+#ifdef __cplusplus
+}
+#endif
+
+__attribute__ ((noinline, noclone)) int
+foo (char *c)
+{
+  return 1;
+}
+
+__attribute__ ((noinline, noclone)) void
+bar (char *c)
+{
+  return;
+}
+
+int main (void)
+{
+  char tpl[20] = "/tmp/test.XXXXXX";
+  int fd = foo (tpl);
+
+  if (fd == -1)
+    return 1;
+
+  bar (tpl);
+
+  if (strcmp (tpl, "/tmp/test.XXXXXX") == 0)
+    return 1;
+
+   return 0;
+}
+
+/* { dg-final { scan-assembler ".section\[ \t]*.rodata\[^\n\r]*(\n|\r\n|\r)\[ \t].align\[ \t]*5\[^\n\r]*(\n|\r\n|\r)\[ \t].set\[ \t]*.LANCHOR\[^\n\r]*(\n|\r\n|\r).LC\[0-9]:\[^\n\r]*(\n|\r\n|\r)\[ \t].ascii\[ \t]*.\"/tmp/test.XXXXXX\[^\n\r]*(\n|\r\n|\r)" } } */
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
     {

Reply via email to