This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][PR sanitizer/78651] Incorrect exception handling when catch clause uses local class and PIC and sanitizer are active
- From: Maxim Ostapenko <m dot ostapenko at samsung dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Cc: Jakub Jelinek <jakub at redhat dot com>, Jonathan Wakely <jwakely dot gcc at gmail dot com>
- Date: Mon, 19 Mar 2018 18:44:39 +0300
- Subject: [PATCH][PR sanitizer/78651] Incorrect exception handling when catch clause uses local class and PIC and sanitizer are active
- Cms-type: 201P
- Dkim-filter: OpenDKIM Filter v2.11.0 mailout2.w1.samsung.com 20180319154451euoutp0245ffee00e55cd2b92c860f57aa3dac0e~dXM6v6K6o0646206462euoutp02-
- References: <CGME20180319154449eucas1p1ce5f24c8b0c276571d2c2bb7858529b8@eucas1p1.samsung.com>
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;