Commit 6dc4a604 by Martin Liska Committed by Martin Liska

Introduce -fsanitize-address-use-after-scope

	* c-warn.c (warn_for_unused_label): Save all labels used
	in goto or in &label.
	* asan.c (enum asan_check_flags): Move the enum to header file.
	(asan_init_shadow_ptr_types): Make type creation more generic.
	(shadow_mem_size): New function.
	(asan_emit_stack_protection): Use newly added ASAN_SHADOW_GRANULARITY.
	Rewritten stack unpoisoning code.
	(build_shadow_mem_access): Add new argument return_address.
	(instrument_derefs): Instrument local variables if use after scope
	sanitization is enabled.
	(asan_store_shadow_bytes): New function.
	(asan_expand_mark_ifn): Likewise.
	(asan_sanitize_stack_p): Moved from asan_sanitize_stack_p.
	* asan.h (enum asan_mark_flags): Moved here from asan.c
	(asan_protect_stack_decl): Protect all declaration that need
	to live in memory.
	(asan_sanitize_use_after_scope): New function.
	(asan_no_sanitize_address_p): Likewise.
	* cfgexpand.c (partition_stack_vars): Consider
	asan_sanitize_use_after_scope in condition.
	(expand_stack_vars): Likewise.
	* common.opt (-fsanitize-address-use-after-scope): New option.
	* doc/invoke.texi (use-after-scope-direct-emission-threshold):
	Explain the parameter.
	* flag-types.h (enum sanitize_code): Define SANITIZE_USE_AFTER_SCOPE.
	* gimplify.c (build_asan_poison_call_expr): New function.
	(asan_poison_variable): Likewise.
	(gimplify_bind_expr): Generate poisoning/unpoisoning for local
	variables that have address taken.
	(gimplify_decl_expr): Likewise.
	(gimplify_target_expr): Likewise for C++ temporaries.
	(sort_by_decl_uid): New function.
	(gimplify_expr): Unpoison all variables for a label we can jump
	from outside of a scope.
	(gimplify_switch_expr): Unpoison variables defined in the switch
	context.
	(gimplify_function_tree): Clear asan_poisoned_variables.
	(asan_poison_variables): New function.
	(warn_switch_unreachable_r): Handle IFN_ASAN_MARK.
	* internal-fn.c (expand_ASAN_MARK): New function.
	* internal-fn.def (ASAN_MARK): Declare.
	* opts.c (finish_options): Handle -fstack-reuse if
	-fsanitize-address-use-after-scope is enabled.
	(common_handle_option): Enable address sanitization if
	-fsanitize-address-use-after-scope is enabled.
	* params.def (PARAM_USE_AFTER_SCOPE_DIRECT_EMISSION_THRESHOLD):
	New parameter.
	* params.h: Likewise.
	* sancov.c (pass_sanopt::execute): Handle IFN_ASAN_MARK.
	* sanitizer.def: Define __asan_poison_stack_memory and
	__asan_unpoison_stack_memory functions.
	* asan.c (asan_mark_poison_p): New function.
	(transform_statements): Handle asan_mark_poison_p calls.
	* gimple.c (nonfreeing_call_p): Handle IFN_ASAN_MARK.

From-SVN: r241896
parent 2447ab85
2016-11-07 Martin Liska <mliska@suse.cz>
* asan.c (enum asan_check_flags): Move the enum to header file.
(asan_init_shadow_ptr_types): Make type creation more generic.
(shadow_mem_size): New function.
(asan_emit_stack_protection): Use newly added ASAN_SHADOW_GRANULARITY.
Rewritten stack unpoisoning code.
(build_shadow_mem_access): Add new argument return_address.
(instrument_derefs): Instrument local variables if use after scope
sanitization is enabled.
(asan_store_shadow_bytes): New function.
(asan_expand_mark_ifn): Likewise.
(asan_sanitize_stack_p): Moved from asan_sanitize_stack_p.
* asan.h (enum asan_mark_flags): Moved here from asan.c
(asan_protect_stack_decl): Protect all declaration that need
to live in memory.
(asan_sanitize_use_after_scope): New function.
(asan_no_sanitize_address_p): Likewise.
* cfgexpand.c (partition_stack_vars): Consider
asan_sanitize_use_after_scope in condition.
(expand_stack_vars): Likewise.
* common.opt (-fsanitize-address-use-after-scope): New option.
* doc/invoke.texi (use-after-scope-direct-emission-threshold):
Explain the parameter.
* flag-types.h (enum sanitize_code): Define SANITIZE_USE_AFTER_SCOPE.
* gimplify.c (build_asan_poison_call_expr): New function.
(asan_poison_variable): Likewise.
(gimplify_bind_expr): Generate poisoning/unpoisoning for local
variables that have address taken.
(gimplify_decl_expr): Likewise.
(gimplify_target_expr): Likewise for C++ temporaries.
(sort_by_decl_uid): New function.
(gimplify_expr): Unpoison all variables for a label we can jump
from outside of a scope.
(gimplify_switch_expr): Unpoison variables defined in the switch
context.
(gimplify_function_tree): Clear asan_poisoned_variables.
(asan_poison_variables): New function.
(warn_switch_unreachable_r): Handle IFN_ASAN_MARK.
* internal-fn.c (expand_ASAN_MARK): New function.
* internal-fn.def (ASAN_MARK): Declare.
* opts.c (finish_options): Handle -fstack-reuse if
-fsanitize-address-use-after-scope is enabled.
(common_handle_option): Enable address sanitization if
-fsanitize-address-use-after-scope is enabled.
* params.def (PARAM_USE_AFTER_SCOPE_DIRECT_EMISSION_THRESHOLD):
New parameter.
* params.h: Likewise.
* sancov.c (pass_sanopt::execute): Handle IFN_ASAN_MARK.
* sanitizer.def: Define __asan_poison_stack_memory and
__asan_unpoison_stack_memory functions.
* asan.c (asan_mark_poison_p): New function.
(transform_statements): Handle asan_mark_poison_p calls.
* gimple.c (nonfreeing_call_p): Handle IFN_ASAN_MARK.
2016-11-07 Tamar Christina <tamar.christina@arm.com> 2016-11-07 Tamar Christina <tamar.christina@arm.com>
PR driver/78196 PR driver/78196
...@@ -29,6 +29,7 @@ extern bool asan_protect_global (tree); ...@@ -29,6 +29,7 @@ extern bool asan_protect_global (tree);
extern void initialize_sanitizer_builtins (void); extern void initialize_sanitizer_builtins (void);
extern tree asan_dynamic_init_call (bool); extern tree asan_dynamic_init_call (bool);
extern bool asan_expand_check_ifn (gimple_stmt_iterator *, bool); extern bool asan_expand_check_ifn (gimple_stmt_iterator *, bool);
extern bool asan_expand_mark_ifn (gimple_stmt_iterator *);
extern gimple_stmt_iterator create_cond_insert_point extern gimple_stmt_iterator create_cond_insert_point
(gimple_stmt_iterator *, bool, bool, bool, basic_block *, basic_block *); (gimple_stmt_iterator *, bool, bool, bool, basic_block *, basic_block *);
...@@ -36,9 +37,14 @@ extern gimple_stmt_iterator create_cond_insert_point ...@@ -36,9 +37,14 @@ extern gimple_stmt_iterator create_cond_insert_point
/* Alias set for accessing the shadow memory. */ /* Alias set for accessing the shadow memory. */
extern alias_set_type asan_shadow_set; extern alias_set_type asan_shadow_set;
/* Hash set of labels that are either used in a goto, or their address
has been taken. */
extern hash_set <tree> *asan_used_labels;
/* Shadow memory is found at /* Shadow memory is found at
(address >> ASAN_SHADOW_SHIFT) + asan_shadow_offset (). */ (address >> ASAN_SHADOW_SHIFT) + asan_shadow_offset (). */
#define ASAN_SHADOW_SHIFT 3 #define ASAN_SHADOW_SHIFT 3
#define ASAN_SHADOW_GRANULARITY (1UL << ASAN_SHADOW_SHIFT)
/* Red zone size, stack and global variables are padded by ASAN_RED_ZONE_SIZE /* Red zone size, stack and global variables are padded by ASAN_RED_ZONE_SIZE
up to 2 * ASAN_RED_ZONE_SIZE - 1 bytes. */ up to 2 * ASAN_RED_ZONE_SIZE - 1 bytes. */
...@@ -55,17 +61,27 @@ extern alias_set_type asan_shadow_set; ...@@ -55,17 +61,27 @@ extern alias_set_type asan_shadow_set;
#define ASAN_STACK_MAGIC_RIGHT 0xf3 #define ASAN_STACK_MAGIC_RIGHT 0xf3
#define ASAN_STACK_MAGIC_PARTIAL 0xf4 #define ASAN_STACK_MAGIC_PARTIAL 0xf4
#define ASAN_STACK_MAGIC_USE_AFTER_RET 0xf5 #define ASAN_STACK_MAGIC_USE_AFTER_RET 0xf5
#define ASAN_STACK_MAGIC_USE_AFTER_SCOPE 0xf8
#define ASAN_STACK_FRAME_MAGIC 0x41b58ab3 #define ASAN_STACK_FRAME_MAGIC 0x41b58ab3
#define ASAN_STACK_RETIRED_MAGIC 0x45e0360e #define ASAN_STACK_RETIRED_MAGIC 0x45e0360e
/* Return true if DECL should be guarded on the stack. */ /* Various flags for Asan builtins. */
enum asan_check_flags
static inline bool
asan_protect_stack_decl (tree decl)
{ {
return DECL_P (decl) && !DECL_ARTIFICIAL (decl); ASAN_CHECK_STORE = 1 << 0,
} ASAN_CHECK_SCALAR_ACCESS = 1 << 1,
ASAN_CHECK_NON_ZERO_LEN = 1 << 2,
ASAN_CHECK_LAST = 1 << 3
};
/* Flags for Asan check builtins. */
enum asan_mark_flags
{
ASAN_MARK_CLOBBER = 1 << 0,
ASAN_MARK_UNCLOBBER = 1 << 1,
ASAN_MARK_LAST = 1 << 2
};
/* Return the size of padding needed to insert after a protected /* Return the size of padding needed to insert after a protected
decl of SIZE. */ decl of SIZE. */
...@@ -81,6 +97,8 @@ extern bool set_asan_shadow_offset (const char *); ...@@ -81,6 +97,8 @@ extern bool set_asan_shadow_offset (const char *);
extern void set_sanitized_sections (const char *); extern void set_sanitized_sections (const char *);
extern bool asan_sanitize_stack_p (void);
/* Return TRUE if builtin with given FCODE will be intercepted by /* Return TRUE if builtin with given FCODE will be intercepted by
libasan. */ libasan. */
...@@ -105,4 +123,30 @@ asan_intercepted_p (enum built_in_function fcode) ...@@ -105,4 +123,30 @@ asan_intercepted_p (enum built_in_function fcode)
|| fcode == BUILT_IN_STRNCMP || fcode == BUILT_IN_STRNCMP
|| fcode == BUILT_IN_STRNCPY; || fcode == BUILT_IN_STRNCPY;
} }
/* Return TRUE if we should instrument for use-after-scope sanity checking. */
static inline bool
asan_sanitize_use_after_scope (void)
{
return (flag_sanitize_address_use_after_scope && asan_sanitize_stack_p ());
}
static inline bool
asan_no_sanitize_address_p (void)
{
return lookup_attribute ("no_sanitize_address",
DECL_ATTRIBUTES (current_function_decl));
}
/* Return true if DECL should be guarded on the stack. */
static inline bool
asan_protect_stack_decl (tree decl)
{
return DECL_P (decl)
&& (!DECL_ARTIFICIAL (decl)
|| (asan_sanitize_use_after_scope () && TREE_ADDRESSABLE (decl)));
}
#endif /* TREE_ASAN */ #endif /* TREE_ASAN */
2016-11-07 Martin Liska <mliska@suse.cz>
* c-warn.c (warn_for_unused_label): Save all labels used
in goto or in &label.
2016-11-03 Jason Merrill <jason@redhat.com> 2016-11-03 Jason Merrill <jason@redhat.com>
* c-cppbuiltin.c (c_cpp_builtins): Correct * c-cppbuiltin.c (c_cpp_builtins): Correct
......
...@@ -28,7 +28,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -28,7 +28,7 @@ along with GCC; see the file COPYING3. If not see
#include "tm_p.h" #include "tm_p.h"
#include "diagnostic.h" #include "diagnostic.h"
#include "intl.h" #include "intl.h"
#include "asan.h"
/* Print a warning if a constant expression had overflow in folding. /* Print a warning if a constant expression had overflow in folding.
Invoke this function on every expression that the language Invoke this function on every expression that the language
...@@ -1627,6 +1627,13 @@ warn_for_unused_label (tree label) ...@@ -1627,6 +1627,13 @@ warn_for_unused_label (tree label)
else else
warning (OPT_Wunused_label, "label %q+D declared but not defined", label); warning (OPT_Wunused_label, "label %q+D declared but not defined", label);
} }
else if (asan_sanitize_use_after_scope ())
{
if (asan_used_labels == NULL)
asan_used_labels = new hash_set<tree> (16);
asan_used_labels->add (label);
}
} }
/* Warn for division by zero according to the value of DIVISOR. LOC /* Warn for division by zero according to the value of DIVISOR. LOC
......
...@@ -868,18 +868,6 @@ union_stack_vars (size_t a, size_t b) ...@@ -868,18 +868,6 @@ union_stack_vars (size_t a, size_t b)
} }
} }
/* Return true if the current function should have its stack frame
protected by address sanitizer. */
static inline bool
asan_sanitize_stack_p (void)
{
return ((flag_sanitize & SANITIZE_ADDRESS)
&& ASAN_STACK
&& !lookup_attribute ("no_sanitize_address",
DECL_ATTRIBUTES (current_function_decl)));
}
/* A subroutine of expand_used_vars. Binpack the variables into /* A subroutine of expand_used_vars. Binpack the variables into
partitions constrained by the interference graph. The overall partitions constrained by the interference graph. The overall
algorithm used is as follows: algorithm used is as follows:
...@@ -941,7 +929,8 @@ partition_stack_vars (void) ...@@ -941,7 +929,8 @@ partition_stack_vars (void)
sizes, as the shorter vars wouldn't be adequately protected. sizes, as the shorter vars wouldn't be adequately protected.
Don't do that for "large" (unsupported) alignment objects, Don't do that for "large" (unsupported) alignment objects,
those aren't protected anyway. */ those aren't protected anyway. */
if (asan_sanitize_stack_p () && isize != jsize if ((asan_sanitize_stack_p ())
&& isize != jsize
&& ialign * BITS_PER_UNIT <= MAX_SUPPORTED_STACK_ALIGNMENT) && ialign * BITS_PER_UNIT <= MAX_SUPPORTED_STACK_ALIGNMENT)
break; break;
...@@ -1128,7 +1117,8 @@ expand_stack_vars (bool (*pred) (size_t), struct stack_vars_data *data) ...@@ -1128,7 +1117,8 @@ expand_stack_vars (bool (*pred) (size_t), struct stack_vars_data *data)
if (alignb * BITS_PER_UNIT <= MAX_SUPPORTED_STACK_ALIGNMENT) if (alignb * BITS_PER_UNIT <= MAX_SUPPORTED_STACK_ALIGNMENT)
{ {
base = virtual_stack_vars_rtx; base = virtual_stack_vars_rtx;
if (asan_sanitize_stack_p () && pred) if ((asan_sanitize_stack_p ())
&& pred)
{ {
HOST_WIDE_INT prev_offset HOST_WIDE_INT prev_offset
= align_base (frame_offset, = align_base (frame_offset,
......
...@@ -986,6 +986,9 @@ fsanitize-recover ...@@ -986,6 +986,9 @@ fsanitize-recover
Common Report Common Report
This switch is deprecated; use -fsanitize-recover= instead. This switch is deprecated; use -fsanitize-recover= instead.
fsanitize-address-use-after-scope
Common Driver Report Var(flag_sanitize_address_use_after_scope) Init(0)
fsanitize-undefined-trap-on-error fsanitize-undefined-trap-on-error
Common Driver Report Var(flag_sanitize_undefined_trap_on_error) Init(0) Common Driver Report Var(flag_sanitize_undefined_trap_on_error) Init(0)
Use trap instead of a library function for undefined behavior sanitization. Use trap instead of a library function for undefined behavior sanitization.
......
...@@ -10290,6 +10290,10 @@ is greater or equal to this number, use callbacks instead of inline checks. ...@@ -10290,6 +10290,10 @@ is greater or equal to this number, use callbacks instead of inline checks.
E.g. to disable inline code use E.g. to disable inline code use
@option{--param asan-instrumentation-with-call-threshold=0}. @option{--param asan-instrumentation-with-call-threshold=0}.
@item use-after-scope-direct-emission-threshold
If size of a local variables in bytes is smaller of equal to this number,
direct instruction emission is utilized to poison and unpoison local variables.
@item chkp-max-ctor-size @item chkp-max-ctor-size
Static constructors generated by Pointer Bounds Checker may become very Static constructors generated by Pointer Bounds Checker may become very
large and significantly increase compile time at optimization level large and significantly increase compile time at optimization level
...@@ -10500,6 +10504,7 @@ thread-safe code. ...@@ -10500,6 +10504,7 @@ thread-safe code.
Enable AddressSanitizer, a fast memory error detector. Enable AddressSanitizer, a fast memory error detector.
Memory access instructions are instrumented to detect Memory access instructions are instrumented to detect
out-of-bounds and use-after-free bugs. out-of-bounds and use-after-free bugs.
The option enables @option{-fsanitize-address-use-after-scope}.
See @uref{https://github.com/google/sanitizers/wiki/AddressSanitizer} for See @uref{https://github.com/google/sanitizers/wiki/AddressSanitizer} for
more details. The run-time behavior can be influenced using the more details. The run-time behavior can be influenced using the
@env{ASAN_OPTIONS} environment variable. When set to @code{help=1}, @env{ASAN_OPTIONS} environment variable. When set to @code{help=1},
...@@ -10511,6 +10516,7 @@ The option can't be combined with @option{-fsanitize=thread}. ...@@ -10511,6 +10516,7 @@ The option can't be combined with @option{-fsanitize=thread}.
@item -fsanitize=kernel-address @item -fsanitize=kernel-address
@opindex fsanitize=kernel-address @opindex fsanitize=kernel-address
Enable AddressSanitizer for Linux kernel. Enable AddressSanitizer for Linux kernel.
The option enables @option{-fsanitize-address-use-after-scope}.
See @uref{https://github.com/google/kasan/wiki} for more details. See @uref{https://github.com/google/kasan/wiki} for more details.
@item -fsanitize=thread @item -fsanitize=thread
...@@ -10710,8 +10716,8 @@ except for @option{-fsanitize=unreachable} and @option{-fsanitize=return}), ...@@ -10710,8 +10716,8 @@ except for @option{-fsanitize=unreachable} and @option{-fsanitize=return}),
@option{-fsanitize=float-cast-overflow}, @option{-fsanitize=float-divide-by-zero}, @option{-fsanitize=float-cast-overflow}, @option{-fsanitize=float-divide-by-zero},
@option{-fsanitize=bounds-strict}, @option{-fsanitize=bounds-strict},
@option{-fsanitize=kernel-address} and @option{-fsanitize=address}. @option{-fsanitize=kernel-address} and @option{-fsanitize=address}.
For these sanitizers error recovery is turned on by default, except @option{-fsanitize=address}, For these sanitizers error recovery is turned on by default,
for which this feature is experimental. except @option{-fsanitize=address}, for which this feature is experimental.
@option{-fsanitize-recover=all} and @option{-fno-sanitize-recover=all} is also @option{-fsanitize-recover=all} and @option{-fno-sanitize-recover=all} is also
accepted, the former enables recovery for all sanitizers that support it, accepted, the former enables recovery for all sanitizers that support it,
the latter disables recovery for all sanitizers that support it. the latter disables recovery for all sanitizers that support it.
...@@ -10733,6 +10739,11 @@ Similarly @option{-fno-sanitize-recover} is equivalent to ...@@ -10733,6 +10739,11 @@ Similarly @option{-fno-sanitize-recover} is equivalent to
-fno-sanitize-recover=undefined,float-cast-overflow,float-divide-by-zero,bounds-strict -fno-sanitize-recover=undefined,float-cast-overflow,float-divide-by-zero,bounds-strict
@end smallexample @end smallexample
@item -fsanitize-address-use-after-scope
@opindex fsanitize-address-use-after-scope
Enable sanitization of local variables to detect use-after-scope bugs.
The option sets @option{-fstack-reuse} to @samp{none}.
@item -fsanitize-undefined-trap-on-error @item -fsanitize-undefined-trap-on-error
@opindex fsanitize-undefined-trap-on-error @opindex fsanitize-undefined-trap-on-error
The @option{-fsanitize-undefined-trap-on-error} option instructs the compiler to The @option{-fsanitize-undefined-trap-on-error} option instructs the compiler to
......
...@@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. If not see
#include "builtins.h" #include "builtins.h"
#include "selftest.h" #include "selftest.h"
#include "gimple-pretty-print.h" #include "gimple-pretty-print.h"
#include "asan.h"
/* All the tuples have their operand vector (if present) at the very bottom /* All the tuples have their operand vector (if present) at the very bottom
...@@ -2629,6 +2630,8 @@ nonfreeing_call_p (gimple *call) ...@@ -2629,6 +2630,8 @@ nonfreeing_call_p (gimple *call)
{ {
case IFN_ABNORMAL_DISPATCHER: case IFN_ABNORMAL_DISPATCHER:
return true; return true;
case IFN_ASAN_MARK:
return tree_to_uhwi (gimple_call_arg (call, 0)) == ASAN_MARK_UNCLOBBER;
default: default:
if (gimple_call_flags (call) & ECF_LEAF) if (gimple_call_flags (call) & ECF_LEAF)
return true; return true;
......
...@@ -237,6 +237,15 @@ expand_ASAN_CHECK (internal_fn, gcall *) ...@@ -237,6 +237,15 @@ expand_ASAN_CHECK (internal_fn, gcall *)
gcc_unreachable (); gcc_unreachable ();
} }
/* This should get expanded in the sanopt pass. */
static void
expand_ASAN_MARK (internal_fn, gcall *)
{
gcc_unreachable ();
}
/* This should get expanded in the tsan pass. */ /* This should get expanded in the tsan pass. */
static void static void
......
...@@ -158,6 +158,7 @@ DEF_INTERNAL_FN (UBSAN_OBJECT_SIZE, ECF_LEAF | ECF_NOTHROW, NULL) ...@@ -158,6 +158,7 @@ DEF_INTERNAL_FN (UBSAN_OBJECT_SIZE, ECF_LEAF | ECF_NOTHROW, NULL)
DEF_INTERNAL_FN (ABNORMAL_DISPATCHER, ECF_NORETURN, NULL) DEF_INTERNAL_FN (ABNORMAL_DISPATCHER, ECF_NORETURN, NULL)
DEF_INTERNAL_FN (BUILTIN_EXPECT, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL) DEF_INTERNAL_FN (BUILTIN_EXPECT, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
DEF_INTERNAL_FN (ASAN_CHECK, ECF_TM_PURE | ECF_LEAF | ECF_NOTHROW, ".R...") DEF_INTERNAL_FN (ASAN_CHECK, ECF_TM_PURE | ECF_LEAF | ECF_NOTHROW, ".R...")
DEF_INTERNAL_FN (ASAN_MARK, ECF_TM_PURE | ECF_LEAF | ECF_NOTHROW, ".R..")
DEF_INTERNAL_FN (ADD_OVERFLOW, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL) DEF_INTERNAL_FN (ADD_OVERFLOW, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
DEF_INTERNAL_FN (SUB_OVERFLOW, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL) DEF_INTERNAL_FN (SUB_OVERFLOW, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
DEF_INTERNAL_FN (MUL_OVERFLOW, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL) DEF_INTERNAL_FN (MUL_OVERFLOW, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
......
...@@ -979,6 +979,25 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, ...@@ -979,6 +979,25 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
opts->x_flag_aggressive_loop_optimizations = 0; opts->x_flag_aggressive_loop_optimizations = 0;
opts->x_flag_strict_overflow = 0; opts->x_flag_strict_overflow = 0;
} }
/* Enable -fsanitize-address-use-after-scope if address sanitizer is
enabled. */
if (opts->x_flag_sanitize
&& !opts_set->x_flag_sanitize_address_use_after_scope)
opts->x_flag_sanitize_address_use_after_scope = true;
/* Force -fstack-reuse=none in case -fsanitize-address-use-after-scope
is enabled. */
if (opts->x_flag_sanitize_address_use_after_scope)
{
if (opts->x_flag_stack_reuse != SR_NONE
&& opts_set->x_flag_stack_reuse != SR_NONE)
error_at (loc,
"-fsanitize-address-use-after-scope requires "
"-fstack-reuse=none option");
opts->x_flag_stack_reuse = SR_NONE;
}
} }
#define LEFT_COLUMN 27 #define LEFT_COLUMN 27
...@@ -1452,8 +1471,8 @@ const struct sanitizer_opts_s sanitizer_opts[] = ...@@ -1452,8 +1471,8 @@ const struct sanitizer_opts_s sanitizer_opts[] =
{ {
#define SANITIZER_OPT(name, flags, recover) \ #define SANITIZER_OPT(name, flags, recover) \
{ #name, flags, sizeof #name - 1, recover } { #name, flags, sizeof #name - 1, recover }
SANITIZER_OPT (address, SANITIZE_ADDRESS | SANITIZE_USER_ADDRESS, true), SANITIZER_OPT (address, (SANITIZE_ADDRESS | SANITIZE_USER_ADDRESS), true),
SANITIZER_OPT (kernel-address, SANITIZE_ADDRESS | SANITIZE_KERNEL_ADDRESS, SANITIZER_OPT (kernel-address, (SANITIZE_ADDRESS | SANITIZE_KERNEL_ADDRESS),
true), true),
SANITIZER_OPT (thread, SANITIZE_THREAD, false), SANITIZER_OPT (thread, SANITIZE_THREAD, false),
SANITIZER_OPT (leak, SANITIZE_LEAK, false), SANITIZER_OPT (leak, SANITIZE_LEAK, false),
...@@ -1781,6 +1800,10 @@ common_handle_option (struct gcc_options *opts, ...@@ -1781,6 +1800,10 @@ common_handle_option (struct gcc_options *opts,
/* Deferred. */ /* Deferred. */
break; break;
case OPT_fsanitize_address_use_after_scope:
opts->x_flag_sanitize_address_use_after_scope = value;
break;
case OPT_fsanitize_recover: case OPT_fsanitize_recover:
if (value) if (value)
opts->x_flag_sanitize_recover opts->x_flag_sanitize_recover
......
...@@ -1168,6 +1168,12 @@ DEFPARAM (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD, ...@@ -1168,6 +1168,12 @@ DEFPARAM (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD,
"in function becomes greater or equal to this number.", "in function becomes greater or equal to this number.",
7000, 0, INT_MAX) 7000, 0, INT_MAX)
DEFPARAM (PARAM_USE_AFTER_SCOPE_DIRECT_EMISSION_THRESHOLD,
"use-after-scope-direct-emission-threshold",
"Use direct poisoning/unpoisoning intructions for variables "
"smaller or equal to this number.",
256, 0, INT_MAX)
DEFPARAM (PARAM_UNINIT_CONTROL_DEP_ATTEMPTS, DEFPARAM (PARAM_UNINIT_CONTROL_DEP_ATTEMPTS,
"uninit-control-dep-attempts", "uninit-control-dep-attempts",
"Maximum number of nested calls to search for control dependencies " "Maximum number of nested calls to search for control dependencies "
......
...@@ -244,5 +244,7 @@ extern void init_param_values (int *params); ...@@ -244,5 +244,7 @@ extern void init_param_values (int *params);
PARAM_VALUE (PARAM_ASAN_USE_AFTER_RETURN) PARAM_VALUE (PARAM_ASAN_USE_AFTER_RETURN)
#define ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD \ #define ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD \
PARAM_VALUE (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD) PARAM_VALUE (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD)
#define ASAN_PARAM_USE_AFTER_SCOPE_DIRECT_EMISSION_THRESHOLD \
((unsigned) PARAM_VALUE (PARAM_USE_AFTER_SCOPE_DIRECT_EMISSION_THRESHOLD))
#endif /* ! GCC_PARAMS_H */ #endif /* ! GCC_PARAMS_H */
...@@ -165,6 +165,10 @@ DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_BEFORE_DYNAMIC_INIT, ...@@ -165,6 +165,10 @@ DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_BEFORE_DYNAMIC_INIT,
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_AFTER_DYNAMIC_INIT, DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_AFTER_DYNAMIC_INIT,
"__asan_after_dynamic_init", "__asan_after_dynamic_init",
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST) BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_CLOBBER_N, "__asan_poison_stack_memory",
BT_FN_VOID_PTR_PTRMODE, 0)
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_UNCLOBBER_N, "__asan_unpoison_stack_memory",
BT_FN_VOID_PTR_PTRMODE, 0)
/* Thread Sanitizer */ /* Thread Sanitizer */
DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_INIT, "__tsan_init", DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_INIT, "__tsan_init",
......
...@@ -732,6 +732,9 @@ pass_sanopt::execute (function *fun) ...@@ -732,6 +732,9 @@ pass_sanopt::execute (function *fun)
case IFN_ASAN_CHECK: case IFN_ASAN_CHECK:
no_next = asan_expand_check_ifn (&gsi, use_calls); no_next = asan_expand_check_ifn (&gsi, use_calls);
break; break;
case IFN_ASAN_MARK:
no_next = asan_expand_mark_ifn (&gsi);
break;
default: default:
break; break;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment