diff options
author | marxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-11-07 10:23:38 +0000 |
---|---|---|
committer | marxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-11-07 10:23:38 +0000 |
commit | 629b6abce95170a3ee8417479e82615fa1e4b67e (patch) | |
tree | 8994878a3b2edbefb1b3d57b17318ab3eeb0db8f /gcc/asan.h | |
parent | a37e105832f282b18ddd869df5e87a34bfe881fa (diff) | |
download | gcc-629b6abce95170a3ee8417479e82615fa1e4b67e.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@241896 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/asan.h')
-rw-r--r-- | gcc/asan.h | 66 |
1 files changed, 55 insertions, 11 deletions
diff --git a/gcc/asan.h b/gcc/asan.h index 7ec693f2b3c..042af1ff799 100644 --- a/gcc/asan.h +++ b/gcc/asan.h @@ -29,6 +29,7 @@ extern bool asan_protect_global (tree); extern void initialize_sanitizer_builtins (void); extern tree asan_dynamic_init_call (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 (gimple_stmt_iterator *, bool, bool, bool, basic_block *, basic_block *); @@ -36,9 +37,14 @@ extern gimple_stmt_iterator create_cond_insert_point /* Alias set for accessing the shadow memory. */ 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 (address >> ASAN_SHADOW_SHIFT) + asan_shadow_offset (). */ #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 up to 2 * ASAN_RED_ZONE_SIZE - 1 bytes. */ @@ -50,22 +56,32 @@ extern alias_set_type asan_shadow_set; the frame. Middle is for padding in between variables, right is above the last protected variable and partial immediately after variables up to ASAN_RED_ZONE_SIZE alignment. */ -#define ASAN_STACK_MAGIC_LEFT 0xf1 -#define ASAN_STACK_MAGIC_MIDDLE 0xf2 -#define ASAN_STACK_MAGIC_RIGHT 0xf3 -#define ASAN_STACK_MAGIC_PARTIAL 0xf4 -#define ASAN_STACK_MAGIC_USE_AFTER_RET 0xf5 +#define ASAN_STACK_MAGIC_LEFT 0xf1 +#define ASAN_STACK_MAGIC_MIDDLE 0xf2 +#define ASAN_STACK_MAGIC_RIGHT 0xf3 +#define ASAN_STACK_MAGIC_PARTIAL 0xf4 +#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_RETIRED_MAGIC 0x45e0360e -/* Return true if DECL should be guarded on the stack. */ - -static inline bool -asan_protect_stack_decl (tree decl) +/* Various flags for Asan builtins. */ +enum asan_check_flags { - 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 decl of SIZE. */ @@ -81,6 +97,8 @@ extern bool set_asan_shadow_offset (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 libasan. */ @@ -105,4 +123,30 @@ asan_intercepted_p (enum built_in_function fcode) || fcode == BUILT_IN_STRNCMP || 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 */ |