Hi all, This patch adds support for dynamic shadow offset in ASan stack instrumentation. It is required by Kernel Address Sanitizer in cases where the shadow offset address is not known at compile-time as the shadow buffer may not be allocated during the early boot stages.
I used a callback function __asan_shadow_offset() to allow GCC to determine the shadow offset at runtime. This option is intended to be triggered by -fsanitize=kernel-address and can be enabled using --param asan-use-shadow-offset-callback=1. I've been working on adding ASan feature to coreboot which is a free software project aimed at replacing the proprietary BIOS (firmware) found in most computers. We had a requirement for the dynamic shadow offset option, so we came up with a GCC patch. You can have a look at the change at https://review.coreboot.org/c/coreboot/+/42794/13. I know many people have expressed a desire for dynamic shadow offset in GCC and this feature is already available in Clang, enabled using -mllvm -asan-force-dynamic-shadow=true flag. So, I thought it would be a useful feature to have in the upcoming GCC version. Thanks, Harshit -------------------------------------------------------------------------- Add support for using a callback function to fetch shadow offset address instead of the fixed value defined at compile-time. This feature is enabled by setting --param asan-use-shadow-offset-callback=1. 2020-07-16 Harshit Sharma <harshitsharm...@gmail.com> gcc/ * asan.c: Use callback function instead of static shadow offset * params.opt: Define new parameter --- gcc/asan.c | 29 ++++++++++++++++++++++------- gcc/params.opt | 4 ++++ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/gcc/asan.c b/gcc/asan.c index 9c9aa4cae35..4870f0a0947 100644 --- a/gcc/asan.c +++ b/gcc/asan.c @@ -1525,13 +1525,28 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb, TREE_ASM_WRITTEN (decl) = 1; TREE_ASM_WRITTEN (id) = 1; emit_move_insn (mem, expand_normal (build_fold_addr_expr (decl))); - shadow_base = expand_binop (Pmode, lshr_optab, base, - gen_int_shift_amount (Pmode, ASAN_SHADOW_SHIFT), - NULL_RTX, 1, OPTAB_DIRECT); - shadow_base - = plus_constant (Pmode, shadow_base, - asan_shadow_offset () - + (base_align_bias >> ASAN_SHADOW_SHIFT)); + if (param_asan_use_shadow_offset_callback) { + rtx addr, shadow_offset_rtx; + ret = init_one_libfunc("__asan_shadow_offset"); + addr= convert_memory_address(ptr_mode, base); + ret = emit_library_call_value(ret, NULL_RTX, LCT_NORMAL, ptr_mode, + addr, ptr_mode); + shadow_offset_rtx = convert_memory_address(Pmode, ret); + shadow_base = expand_binop (Pmode, lshr_optab, base, + gen_int_shift_amount (Pmode, ASAN_SHADOW_SHIFT), + NULL_RTX, 1, OPTAB_DIRECT); + shadow_base = expand_binop (Pmode, add_optab, shadow_base, + shadow_offset_rtx, NULL_RTX, 1, OPTAB_LIB_WIDEN); + shadow_base = plus_constant (Pmode, shadow_base, + (base_align_bias >> ASAN_SHADOW_SHIFT)); + } else { + shadow_base = expand_binop (Pmode, lshr_optab, base, + gen_int_shift_amount (Pmode, ASAN_SHADOW_SHIFT), + NULL_RTX, 1, OPTAB_DIRECT); + shadow_base = plus_constant (Pmode, shadow_base, + asan_shadow_offset () + + (base_align_bias >> ASAN_SHADOW_SHIFT)); + } gcc_assert (asan_shadow_set != -1 && (ASAN_RED_ZONE_SIZE >> ASAN_SHADOW_SHIFT) == 4); shadow_mem = gen_rtx_MEM (SImode, shadow_base); diff --git a/gcc/params.opt b/gcc/params.opt index e29a44e7712..5fcf9e7f432 100644 --- a/gcc/params.opt +++ b/gcc/params.opt @@ -50,6 +50,10 @@ Enable asan store operations protection. Common Joined UInteger Var(param_asan_instrumentation_with_call_threshold) Init(7000) Param Optimization Use callbacks instead of inline code if number of accesses in function becomes greater or equal to this number. +-param=asan-use-shadow-offset-callback= +Common Joined UInteger Var(param_asan_use_shadow_offset_callback) Init(0) Param Optimization +Use shadow offset callback function at runtime instead of fixed value at compile time at the cost of runtime overhead. + -param=asan-memintrin= Common Joined UInteger Var(param_asan_memintrin) Init(1) IntegerRange(0, 1) Param Optimization Enable asan builtin functions protection. -- 2.17.1