From: Martin Liska Date: Mon, 24 Sep 2018 11:22:38 +0000 (+0200) Subject: Unpoison variable partition properly (PR sanitizer/85774). X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=bf9f9292131058faa03177b7a0d6f1c265eb29f2;p=gcc.git Unpoison variable partition properly (PR sanitizer/85774). 2018-09-24 Martin Liska 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 PR sanitizer/85774 * g++.dg/asan/pr85774.C: New test. From-SVN: r264528 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5c07395eefd..fc16b257d5a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2018-09-24 Martin Liska + + 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 PR tree-optimization/63155 diff --git a/gcc/asan.c b/gcc/asan.c index e71ab2cc710..235e219479d 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 *asan_handled_variables = NULL; +hash_set *asan_handled_variables = NULL; hash_set *asan_used_labels = NULL; diff --git a/gcc/asan.h b/gcc/asan.h index 412af220597..2f431b4f938 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 *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 c8d7805308c..35ca276e4ad 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 6a3f97b0e0f..569d20f6fd0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-09-24 Martin Liska + + PR sanitizer/85774 + * g++.dg/asan/pr85774.C: New test. + 2018-09-24 Alexandre Oliva 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 00000000000..c033abfd69b --- /dev/null +++ b/gcc/testsuite/g++.dg/asan/pr85774.C @@ -0,0 +1,51 @@ +/* PR sanitizer/85774 */ +/* { dg-do run } */ + +#include + +void +DoSomething () +{ +} + +void +DoFunc (const std::function &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; +}