[PATCH] Add support for dynamic shadow offset

2020-07-16 Thread Harshit Sharma via Gcc-patches
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-16Harshit Sharma

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


Emit a variable defined in gcc

2020-06-30 Thread Harshit Sharma via Gcc-patches
Hello,
I am working on a gcc patch for asan. The patch is almost ready except one
thing. To make sure that the user has applied this patch before using asan
feature, I want to declare an additional variable in gcc which is
referenced by our source code so that if this patch is missing, the user
gets an error compiling the code because the reference to this variable
will not be resolved.

I am still new to gcc development. So, can anyone tell me how can I make
gcc emit this variable?


Thanks,
Harshit


Emit a variable defined in gcc

2020-06-29 Thread Harshit Sharma via Gcc-patches
Hello,
I am working on a gcc patch for asan. The patch is almost ready except one
thing. To make sure that the user has applied this patch before using asan
feature, I want to declare an additional variable in gcc which is
referenced by our source code so that if this patch is missing, the user
gets an error compiling the code because the reference to this variable
will not be resolved.

I am still new to gcc development. So, can anyone tell me how can I make
gcc emit this variable?


Thanks,
Harshit