From 7504c3bf61443f9255b0a0caf310b5300b59b92d Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 17 Apr 2018 22:22:50 +0200 Subject: [PATCH] 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 --- gcc/ChangeLog | 10 ++++++++++ gcc/asan.c | 13 ++++++------- gcc/builtins.c | 18 ++++++++++++------ 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a136e541e13..cce4d3ddb9b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2018-04-17 Jakub Jelinek + + 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 * config/rs6000/rs6000-protos.h (rs6000_builtin_is_supported_p): diff --git a/gcc/asan.c b/gcc/asan.c index df9bc7b3404..e71ab2cc710 100644 --- a/gcc/asan.c +++ b/gcc/asan.c @@ -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 diff --git a/gcc/builtins.c b/gcc/builtins.c index 93c617e81ff..a71555e8198 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -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); -- 2.30.2