public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Add support for dynamic shadow offset
@ 2020-07-17  2:46 Harshit Sharma
  0 siblings, 0 replies; only message in thread
From: Harshit Sharma @ 2020-07-17  2:46 UTC (permalink / raw)
  To: 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-16    Harshit Sharma    <harshitsharmajs@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

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-07-17  2:46 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-17  2:46 [PATCH] Add support for dynamic shadow offset Harshit Sharma

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).