Unpoison variable partition properly (PR sanitizer/85774).
authorMartin Liska <mliska@suse.cz>
Mon, 24 Sep 2018 11:22:38 +0000 (13:22 +0200)
committerMartin Liska <marxin@gcc.gnu.org>
Mon, 24 Sep 2018 11:22:38 +0000 (11:22 +0000)
2018-09-24  Martin Liska  <mliska@suse.cz>

PR sanitizer/85774
* asan.c: Make asan_handled_variables extern.
* asan.h: Likewise.
* cfgexpand.c (expand_stack_vars): Make sure
a representative is unpoison if another
variable in the partition is handled by
use-after-scope sanitization.
2018-09-24  Martin Liska  <mliska@suse.cz>

PR sanitizer/85774
* g++.dg/asan/pr85774.C: New test.

From-SVN: r264528

gcc/ChangeLog
gcc/asan.c
gcc/asan.h
gcc/cfgexpand.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/asan/pr85774.C [new file with mode: 0644]

index 5c07395..fc16b25 100644 (file)
@@ -1,3 +1,13 @@
+2018-09-24  Martin Liska  <mliska@suse.cz>
+
+       PR sanitizer/85774
+       * asan.c: Make asan_handled_variables extern.
+       * asan.h: Likewise.
+       * cfgexpand.c (expand_stack_vars): Make sure
+       a representative is unpoison if another
+       variable in the partition is handled by
+       use-after-scope sanitization.
+
 2018-09-24  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/63155
index e71ab2c..235e219 100644 (file)
@@ -253,7 +253,7 @@ static tree last_alloca_addr;
 /* Set of variable declarations that are going to be guarded by
    use-after-scope sanitizer.  */
 
-static hash_set<tree> *asan_handled_variables = NULL;
+hash_set<tree> *asan_handled_variables = NULL;
 
 hash_set <tree> *asan_used_labels = NULL;
 
index 412af22..2f431b4 100644 (file)
@@ -110,6 +110,8 @@ extern bool asan_sanitize_stack_p (void);
 
 extern bool asan_sanitize_allocas_p (void);
 
+extern hash_set<tree> *asan_handled_variables;
+
 /* Return TRUE if builtin with given FCODE will be intercepted by
    libasan.  */
 
index c8d7805..35ca276 100644 (file)
@@ -1155,6 +1155,20 @@ expand_stack_vars (bool (*pred) (size_t), struct stack_vars_data *data)
              if (repr_decl == NULL_TREE)
                repr_decl = stack_vars[i].decl;
              data->asan_decl_vec.safe_push (repr_decl);
+
+             /* Make sure a representative is unpoison if another
+                variable in the partition is handled by
+                use-after-scope sanitization.  */
+             if (asan_handled_variables != NULL
+                 && !asan_handled_variables->contains (repr_decl))
+               {
+                 for (j = i; j != EOC; j = stack_vars[j].next)
+                   if (asan_handled_variables->contains (stack_vars[j].decl))
+                     break;
+                 if (j != EOC)
+                   asan_handled_variables->add (repr_decl);
+               }
+
              data->asan_alignb = MAX (data->asan_alignb, alignb);
              if (data->asan_base == NULL)
                data->asan_base = gen_reg_rtx (Pmode);
index 6a3f97b..569d20f 100644 (file)
@@ -1,3 +1,8 @@
+2018-09-24  Martin Liska  <mliska@suse.cz>
+
+       PR sanitizer/85774
+       * g++.dg/asan/pr85774.C: New test.
+
 2018-09-24  Alexandre Oliva <oliva@adacore.com>
 
        PR middle-end/87054
diff --git a/gcc/testsuite/g++.dg/asan/pr85774.C b/gcc/testsuite/g++.dg/asan/pr85774.C
new file mode 100644 (file)
index 0000000..c033abf
--- /dev/null
@@ -0,0 +1,51 @@
+/* PR sanitizer/85774 */
+/* { dg-do run } */
+
+#include <functional>
+
+void
+DoSomething ()
+{
+}
+
+void
+DoFunc (const std::function<void(void)> &func)
+{
+  func ();
+}
+
+void
+Setup ()
+{
+  switch (1)
+    {
+    case 1:
+      {
+       DoFunc ([]() {});
+       break;
+      }
+    case 2:
+      {
+       DoFunc ([]() {});
+       break;
+      }
+    default:
+      break;
+    }
+
+  DoSomething ();
+}
+
+void
+DemostrateBadPoisoning ()
+{
+  DoFunc ([]() {});
+}
+
+int
+main ()
+{
+  Setup ();
+  DemostrateBadPoisoning ();
+  return 0;
+}