Commit 8240018b by Jakub Jelinek Committed by Dodji Seketeli

Implement protection of global variables

This patch implements the protection of global variables.  See the
comments appended to the beginning of the asan.c file.

	* varasm.c: Include asan.h.
	(assemble_noswitch_variable): Grow size by asan_red_zone_size
	if decl is asan protected.
	(place_block_symbol): Likewise.
	(assemble_variable): If decl is asan protected, increase
	DECL_ALIGN if needed, and for decls emitted using
	assemble_variable_contents append padding zeros after it.
	* Makefile.in (varasm.o): Depend on asan.h.
	* asan.c: Include output.h.
	(asan_pp, asan_pp_initialized, asan_ctor_statements): New variables.
	(asan_pp_initialize, asan_pp_string): New functions.
	(asan_emit_stack_protection): Use asan_pp{,_initialized}
	instead of local pp{,_initialized} vars, use asan_pp_initialize
	and asan_pp_string helpers.
	(asan_needs_local_alias, asan_protect_global,
	asan_global_struct, asan_add_global): New functions.
	(asan_finish_file): Protect global vars that can be protected. Use
	asan_ctor_statements instead of ctor_statements
	* asan.h (asan_protect_global): New prototype.
	(asan_red_zone_size): New inline function.

Co-Authored-By: Wei Mi <wmi@google.com>

From-SVN: r193437
parent f3ddd692
2012-11-12 Jakub Jelinek <jakub@redhat.com> 2012-11-12 Jakub Jelinek <jakub@redhat.com>
Wei Mi <wmi@google.com>
* varasm.c: Include asan.h.
(assemble_noswitch_variable): Grow size by asan_red_zone_size
if decl is asan protected.
(place_block_symbol): Likewise.
(assemble_variable): If decl is asan protected, increase
DECL_ALIGN if needed, and for decls emitted using
assemble_variable_contents append padding zeros after it.
* Makefile.in (varasm.o): Depend on asan.h.
* asan.c: Include output.h.
(asan_pp, asan_pp_initialized, asan_ctor_statements): New variables.
(asan_pp_initialize, asan_pp_string): New functions.
(asan_emit_stack_protection): Use asan_pp{,_initialized}
instead of local pp{,_initialized} vars, use asan_pp_initialize
and asan_pp_string helpers.
(asan_needs_local_alias, asan_protect_global,
asan_global_struct, asan_add_global): New functions.
(asan_finish_file): Protect global vars that can be protected. Use
asan_ctor_statements instead of ctor_statements
* asan.h (asan_protect_global): New prototype.
(asan_red_zone_size): New inline function.
2012-11-12 Jakub Jelinek <jakub@redhat.com>
* Makefile.in (asan.o): Depend on $(EXPR_H) $(OPTABS_H). * Makefile.in (asan.o): Depend on $(EXPR_H) $(OPTABS_H).
(cfgexpand.o): Depend on asan.h. (cfgexpand.o): Depend on asan.h.
...@@ -2719,7 +2719,7 @@ varasm.o : varasm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ ...@@ -2719,7 +2719,7 @@ varasm.o : varasm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
output.h $(DIAGNOSTIC_CORE_H) xcoffout.h debug.h $(GGC_H) $(TM_P_H) \ output.h $(DIAGNOSTIC_CORE_H) xcoffout.h debug.h $(GGC_H) $(TM_P_H) \
$(HASHTAB_H) $(TARGET_H) langhooks.h gt-varasm.h $(BASIC_BLOCK_H) \ $(HASHTAB_H) $(TARGET_H) langhooks.h gt-varasm.h $(BASIC_BLOCK_H) \
$(CGRAPH_H) $(TARGET_DEF_H) tree-mudflap.h \ $(CGRAPH_H) $(TARGET_DEF_H) tree-mudflap.h \
pointer-set.h $(COMMON_TARGET_H) pointer-set.h $(COMMON_TARGET_H) asan.h
function.o : function.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_ERROR_H) \ function.o : function.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_ERROR_H) \
$(TREE_H) $(GIMPLE_H) $(FLAGS_H) $(FUNCTION_H) $(EXPR_H) \ $(TREE_H) $(GIMPLE_H) $(FLAGS_H) $(FUNCTION_H) $(EXPR_H) \
$(OPTABS_H) $(LIBFUNCS_H) $(REGS_H) hard-reg-set.h insn-config.h $(RECOG_H) \ $(OPTABS_H) $(LIBFUNCS_H) $(REGS_H) hard-reg-set.h insn-config.h $(RECOG_H) \
......
...@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see
extern void asan_finish_file (void); extern void asan_finish_file (void);
extern rtx asan_emit_stack_protection (rtx, HOST_WIDE_INT *, tree *, int); extern rtx asan_emit_stack_protection (rtx, HOST_WIDE_INT *, tree *, int);
extern bool asan_protect_global (tree);
/* 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;
...@@ -56,4 +57,14 @@ asan_protect_stack_decl (tree decl) ...@@ -56,4 +57,14 @@ asan_protect_stack_decl (tree decl)
return DECL_P (decl) && !DECL_ARTIFICIAL (decl); return DECL_P (decl) && !DECL_ARTIFICIAL (decl);
} }
/* Return the size of padding needed to insert after a protected
decl of SIZE. */
static inline unsigned int
asan_red_zone_size (unsigned int size)
{
unsigned int c = size & (ASAN_RED_ZONE_SIZE - 1);
return c ? 2 * ASAN_RED_ZONE_SIZE - c : ASAN_RED_ZONE_SIZE;
}
#endif /* TREE_ASAN */ #endif /* TREE_ASAN */
...@@ -51,6 +51,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -51,6 +51,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-mudflap.h" #include "tree-mudflap.h"
#include "cgraph.h" #include "cgraph.h"
#include "pointer-set.h" #include "pointer-set.h"
#include "asan.h"
#ifdef XCOFF_DEBUGGING_INFO #ifdef XCOFF_DEBUGGING_INFO
#include "xcoffout.h" /* Needed for external data #include "xcoffout.h" /* Needed for external data
...@@ -1831,6 +1832,9 @@ assemble_noswitch_variable (tree decl, const char *name, section *sect) ...@@ -1831,6 +1832,9 @@ assemble_noswitch_variable (tree decl, const char *name, section *sect)
size = tree_low_cst (DECL_SIZE_UNIT (decl), 1); size = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
rounded = size; rounded = size;
if (flag_asan && asan_protect_global (decl))
size += asan_red_zone_size (size);
/* Don't allocate zero bytes of common, /* Don't allocate zero bytes of common,
since that means "undefined external" in the linker. */ since that means "undefined external" in the linker. */
if (size == 0) if (size == 0)
...@@ -1897,6 +1901,7 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED, ...@@ -1897,6 +1901,7 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
const char *name; const char *name;
rtx decl_rtl, symbol; rtx decl_rtl, symbol;
section *sect; section *sect;
bool asan_protected = false;
/* This function is supposed to handle VARIABLES. Ensure we have one. */ /* This function is supposed to handle VARIABLES. Ensure we have one. */
gcc_assert (TREE_CODE (decl) == VAR_DECL); gcc_assert (TREE_CODE (decl) == VAR_DECL);
...@@ -1984,6 +1989,15 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED, ...@@ -1984,6 +1989,15 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
/* Compute the alignment of this data. */ /* Compute the alignment of this data. */
align_variable (decl, dont_output_data); align_variable (decl, dont_output_data);
if (flag_asan
&& asan_protect_global (decl))
{
asan_protected = true;
DECL_ALIGN (decl) = MAX (DECL_ALIGN (decl),
ASAN_RED_ZONE_SIZE * BITS_PER_UNIT);
}
set_mem_align (decl_rtl, DECL_ALIGN (decl)); set_mem_align (decl_rtl, DECL_ALIGN (decl));
if (TREE_PUBLIC (decl)) if (TREE_PUBLIC (decl))
...@@ -2022,6 +2036,12 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED, ...@@ -2022,6 +2036,12 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
if (DECL_ALIGN (decl) > BITS_PER_UNIT) if (DECL_ALIGN (decl) > BITS_PER_UNIT)
ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (DECL_ALIGN_UNIT (decl))); ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (DECL_ALIGN_UNIT (decl)));
assemble_variable_contents (decl, name, dont_output_data); assemble_variable_contents (decl, name, dont_output_data);
if (asan_protected)
{
unsigned HOST_WIDE_INT int size
= tree_low_cst (DECL_SIZE_UNIT (decl), 1);
assemble_zeros (asan_red_zone_size (size));
}
} }
} }
...@@ -6926,6 +6946,8 @@ place_block_symbol (rtx symbol) ...@@ -6926,6 +6946,8 @@ place_block_symbol (rtx symbol)
decl = SYMBOL_REF_DECL (symbol); decl = SYMBOL_REF_DECL (symbol);
alignment = DECL_ALIGN (decl); alignment = DECL_ALIGN (decl);
size = tree_low_cst (DECL_SIZE_UNIT (decl), 1); size = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
if (flag_asan && asan_protect_global (decl))
size += asan_red_zone_size (size);
} }
/* Calculate the object's offset from the start of the block. */ /* Calculate the object's offset from the start of the block. */
......
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