aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2018-09-24 13:22:38 +0200
committerMartin Liska <marxin@gcc.gnu.org>2018-09-24 11:22:38 +0000
commitbf9f9292131058faa03177b7a0d6f1c265eb29f2 (patch)
tree91afbb9244655cef727a35df6ce34bfce80453b6 /gcc
parent54b7d98ec40895719d5d62be02e5f03d08aac543 (diff)
downloadgcc-bf9f9292131058faa03177b7a0d6f1c265eb29f2.zip
gcc-bf9f9292131058faa03177b7a0d6f1c265eb29f2.tar.gz
gcc-bf9f9292131058faa03177b7a0d6f1c265eb29f2.tar.bz2
Unpoison variable partition properly (PR sanitizer/85774).
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/asan.c2
-rw-r--r--gcc/asan.h2
-rw-r--r--gcc/cfgexpand.c14
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/asan/pr85774.C51
6 files changed, 83 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5c07395..fc16b25 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/asan.c b/gcc/asan.c
index e71ab2c..235e219 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -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;
diff --git a/gcc/asan.h b/gcc/asan.h
index 412af22..2f431b4 100644
--- a/gcc/asan.h
+++ b/gcc/asan.h
@@ -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. */
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index c8d7805..35ca276 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -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);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6a3f97b..569d20f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..c033abf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/asan/pr85774.C
@@ -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;
+}