Commit 7504c3bf by Jakub Jelinek Committed by Jakub Jelinek

re PR sanitizer/85230 (asan: false positives in kernel on allocas)

	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
parent aa4ec2cd
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):
......
......@@ -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
......
......@@ -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);
......
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