re PR sanitizer/85230 (asan: false positives in kernel on allocas)
authorJakub Jelinek <jakub@redhat.com>
Tue, 17 Apr 2018 20:22:50 +0000 (22:22 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 17 Apr 2018 20:22:50 +0000 (22:22 +0200)
PR sanitizer/85230
* asan.c (handle_builtin_stack_restore): Adjust comment.  Emit
__asan_allocas_unpoison call and last_alloca_addr = new_sp before
__builtin_stack_restore rather than after it.
* builtins.c (expand_asan_emit_allocas_unpoison): Pass
arg1 + (virtual_dynamic_stack_rtx - stack_pointer_rtx) as second
argument instead of virtual_dynamic_stack_rtx.

From-SVN: r259446

gcc/ChangeLog
gcc/asan.c
gcc/builtins.c

index a136e54..cce4d3d 100644 (file)
@@ -1,3 +1,13 @@
+2018-04-17  Jakub Jelinek  <jakub@redhat.com>
+
+       PR sanitizer/85230
+       * asan.c (handle_builtin_stack_restore): Adjust comment.  Emit
+       __asan_allocas_unpoison call and last_alloca_addr = new_sp before
+       __builtin_stack_restore rather than after it.
+       * builtins.c (expand_asan_emit_allocas_unpoison): Pass
+       arg1 + (virtual_dynamic_stack_rtx - stack_pointer_rtx) as second
+       argument instead of virtual_dynamic_stack_rtx.
+
 2018-04-17  Kelvin Nilsen  <kelvin@gcc.gnu.org>
 
        * config/rs6000/rs6000-protos.h (rs6000_builtin_is_supported_p):
index df9bc7b..e71ab2c 100644 (file)
@@ -554,14 +554,14 @@ get_last_alloca_addr ()
   return last_alloca_addr;
 }
 
-/* Insert __asan_allocas_unpoison (top, bottom) call after
+/* Insert __asan_allocas_unpoison (top, bottom) call before
    __builtin_stack_restore (new_sp) call.
    The pseudocode of this routine should look like this:
-     __builtin_stack_restore (new_sp);
      top = last_alloca_addr;
      bot = new_sp;
      __asan_allocas_unpoison (top, bot);
      last_alloca_addr = new_sp;
+     __builtin_stack_restore (new_sp);
    In general, we can't use new_sp as bot parameter because on some
    architectures SP has non zero offset from dynamic stack area.  Moreover, on
    some architectures this offset (STACK_DYNAMIC_OFFSET) becomes known for each
@@ -570,9 +570,8 @@ get_last_alloca_addr ()
    http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html#DYNAM-STACK.
    To overcome the issue we use following trick: pass new_sp as a second
    parameter to __asan_allocas_unpoison and rewrite it during expansion with
-   virtual_dynamic_stack_rtx later in expand_asan_emit_allocas_unpoison
-   function.
-*/
+   new_sp + (virtual_dynamic_stack_rtx - sp) later in
+   expand_asan_emit_allocas_unpoison function.  */
 
 static void
 handle_builtin_stack_restore (gcall *call, gimple_stmt_iterator *iter)
@@ -584,9 +583,9 @@ handle_builtin_stack_restore (gcall *call, gimple_stmt_iterator *iter)
   tree restored_stack = gimple_call_arg (call, 0);
   tree fn = builtin_decl_implicit (BUILT_IN_ASAN_ALLOCAS_UNPOISON);
   gimple *g = gimple_build_call (fn, 2, last_alloca, restored_stack);
-  gsi_insert_after (iter, g, GSI_NEW_STMT);
+  gsi_insert_before (iter, g, GSI_SAME_STMT);
   g = gimple_build_assign (last_alloca, restored_stack);
-  gsi_insert_after (iter, g, GSI_NEW_STMT);
+  gsi_insert_before (iter, g, GSI_SAME_STMT);
 }
 
 /* Deploy and poison redzones around __builtin_alloca call.  To do this, we
index 93c617e..a71555e 100644 (file)
@@ -5072,18 +5072,24 @@ expand_builtin_alloca (tree exp)
   return result;
 }
 
-/* Emit a call to __asan_allocas_unpoison call in EXP.  Replace second argument
-   of the call with virtual_stack_dynamic_rtx because in asan pass we emit a
-   dummy value into second parameter relying on this function to perform the
-   change.  See motivation for this in comment to handle_builtin_stack_restore
-   function.  */
+/* Emit a call to __asan_allocas_unpoison call in EXP.  Add to second argument
+   of the call virtual_stack_dynamic_rtx - stack_pointer_rtx, which is the
+   STACK_DYNAMIC_OFFSET value.  See motivation for this in comment to
+   handle_builtin_stack_restore function.  */
 
 static rtx
 expand_asan_emit_allocas_unpoison (tree exp)
 {
   tree arg0 = CALL_EXPR_ARG (exp, 0);
+  tree arg1 = CALL_EXPR_ARG (exp, 1);
   rtx top = expand_expr (arg0, NULL_RTX, ptr_mode, EXPAND_NORMAL);
-  rtx bot = convert_memory_address (ptr_mode, virtual_stack_dynamic_rtx);
+  rtx bot = expand_expr (arg1, NULL_RTX, ptr_mode, EXPAND_NORMAL);
+  rtx off = expand_simple_binop (Pmode, MINUS, virtual_stack_dynamic_rtx,
+                                stack_pointer_rtx, NULL_RTX, 0,
+                                OPTAB_LIB_WIDEN);
+  off = convert_modes (ptr_mode, Pmode, off, 0);
+  bot = expand_simple_binop (ptr_mode, PLUS, bot, off, NULL_RTX, 0,
+                            OPTAB_LIB_WIDEN);
   rtx ret = init_one_libfunc ("__asan_allocas_unpoison");
   ret = emit_library_call_value (ret, NULL_RTX, LCT_NORMAL, ptr_mode,
                                 top, ptr_mode, bot, ptr_mode);