This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][PR sanitizer/78651] Incorrect exception handling when catch clause uses local class and PIC and sanitizer are active


Hi,


as noted in bugzilla, ASan inserts redzones for  `.LDFCM*' variables and breaks internal ABI between GCC and libstdc++ because libstdc++ tries to obtain a pointer to `typeinfo for (anonymous namespace)::SomeRandomType' from a constant offset from `.LDFCM*' labels and hits these redzones. This can be trivially fixed by not sanitizing `.LDFCM*' variables (and other debug variables) at all.

Attached patch is tested/bootstrapped on x86_64-unknown-linux-gnu and ppc64le-redhat-linux targets.

Is it OK for trunk now, or should I wait for stage 1?


-Maxim

gcc/

	PR sanitizer/78651
	* dwarf2asm.c (dw2_output_indirect_constant_1): Call
	assemble_variable with new parameter.
	* output.h (assemble_variable): Add new parameter.
	* varasm.c (assemble_variable): Add new parameter. Do not
	protect variable with ASan if is_debug_var is true.

gcc/testsuite/ChangeLog:

	PR sanitizer/78651
	* g++.dg/asan/pr78651.C: New test.

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b5b5559..a26f05e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2018-03-19  Maxim Ostapenko  <m.ostapenko@samsung.com>
+
+	PR sanitizer/78651
+	* dwarf2asm.c (dw2_output_indirect_constant_1): Call assemble_variable
+	with new parameter.
+	* output.h (assemble_variable): Add new parameter.
+	* varasm.c (assemble_variable): Add new parameter. Do not protect
+	variable with ASan if is_debug_var is true.
+
 2018-03-19  Richard Biener  <rguenther@suse.de>
 
 	PR tree-optimization/84929
diff --git a/gcc/dwarf2asm.c b/gcc/dwarf2asm.c
index e9b18b8..5c90994 100644
--- a/gcc/dwarf2asm.c
+++ b/gcc/dwarf2asm.c
@@ -967,7 +967,7 @@ dw2_output_indirect_constant_1 (const char *sym, tree id)
     }
 
   sym_ref = gen_rtx_SYMBOL_REF (Pmode, sym);
-  assemble_variable (decl, 1, 1, 1);
+  assemble_variable (decl, 1, 1, 1, 1);
   assemble_integer (sym_ref, POINTER_SIZE_UNITS, POINTER_SIZE, 1);
 
   return 0;
diff --git a/gcc/output.h b/gcc/output.h
index f708cc7..678c370 100644
--- a/gcc/output.h
+++ b/gcc/output.h
@@ -200,7 +200,7 @@ extern void assemble_end_function (tree, const char *);
    to define things that have had only tentative definitions.
    DONT_OUTPUT_DATA if nonzero means don't actually output the
    initial value (that will be done by the caller).  */
-extern void assemble_variable (tree, int, int, int);
+extern void assemble_variable (tree, int, int, int, int is_debug_var = 0);
 
 /* Put the vtable verification constructor initialization function
    into the preinit array.  */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 868d8e8..6ff9217 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2018-03-19  Maxim Ostapenko  <m.ostapenko@samsung.com>
+
+	PR sanitizer/78651
+	* g++.dg/asan/pr78651.C: New test.
+
 2018-03-19  Richard Biener  <rguenther@suse.de>
 
 	PR tree-optimization/84929
diff --git a/gcc/testsuite/g++.dg/asan/pr78651.C b/gcc/testsuite/g++.dg/asan/pr78651.C
new file mode 100644
index 0000000..3f14be7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/asan/pr78651.C
@@ -0,0 +1,24 @@
+// { dg-do run { target fpic } }
+
+struct A { };
+
+namespace {
+
+void thisThrows () {
+  throw A();
+}
+
+struct SomeRandomType {};
+}
+
+int main() {
+  try {
+    thisThrows();
+  }
+  catch (SomeRandomType) {
+    throw;
+  }
+  catch (A) {
+  }
+  return 0;
+}
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 2b5c70c..b18d011 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -2158,11 +2158,14 @@ assemble_undefined_decl (tree decl)
    AT_END is nonzero if this is the special handling, at end of compilation,
    to define things that have had only tentative definitions.
    DONT_OUTPUT_DATA if nonzero means don't actually output the
-   initial value (that will be done by the caller).  */
+   initial value (that will be done by the caller).
+   IS_DEBUG_VAR if nonzero that we are assembling debug variable.
+   This information is useful for ASan, see pr78651.  */
 
 void
 assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
-		   int at_end ATTRIBUTE_UNUSED, int dont_output_data)
+		   int at_end ATTRIBUTE_UNUSED, int dont_output_data,
+		   int is_debug_var)
 {
   const char *name;
   rtx decl_rtl, symbol;
@@ -2258,6 +2261,7 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
   align_variable (decl, dont_output_data);
 
   if ((flag_sanitize & SANITIZE_ADDRESS)
+      && !is_debug_var
       && asan_protect_global (decl))
     {
       asan_protected = true;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]