From patchwork Mon Jul 21 19:00:11 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Preobrazhensky X-Patchwork-Id: 372180 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4F6831400F1 for ; Tue, 22 Jul 2014 05:01:09 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:from:date:message-id:subject:to:cc:content-type; q=dns; s=default; b=I07zLhiCFwYsZiD77vxEBGn7jZMHHTbG+q4f4vOE+Az Eto56Z32KbD3ss92fFdbsdQypsdGV0/lSeljydruXG7nW9WXUJ03gBo4IAFr8COM VQ1faPf3nwnhTQ1xB5tgegcWioXBZheUr7FZPvjqKg5a06wyKT28f4Q5TXyhwk+U = DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:from:date:message-id:subject:to:cc:content-type; s=default; bh=7PeytGzGReshy2Kp3JE1ObC6TC4=; b=NCWMW7cX/1jhsaklI T5Ip7q6oMD44VRoItmVsPxv3RKqEgcfynpHkp7lP9QacIJEuEeiDvunVMauZIGPL vsctEjy7hhobYcR4QH2nNcvGLpGvTIHvk6pDcz9LtMOGhmUc5mThsCKsIlz6NUUf BMvsTj29oK5aSEcb4OZm+eco4w= Received: (qmail 16679 invoked by alias); 21 Jul 2014 19:01:01 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 16613 invoked by uid 89); 21 Jul 2014 19:00:58 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-vc0-f179.google.com Received: from mail-vc0-f179.google.com (HELO mail-vc0-f179.google.com) (209.85.220.179) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Mon, 21 Jul 2014 19:00:55 +0000 Received: by mail-vc0-f179.google.com with SMTP id hq11so11293058vcb.24 for ; Mon, 21 Jul 2014 12:00:52 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:from:date:message-id:subject:to:cc :content-type; bh=KEoLxBvqEDkwbNpTESoRVStg1n2yR2BDeMabevtD/5o=; b=Kzan6lF0cyZ0o4aXfivX2rD8cOIs5KMv3flPS2Ix45Ayb45faXX/r3ZHjOVTSnzuOz xP1KVgbuyQAYFFURE3iqW22irzXweBGfEqRk2+hwDFwHANHmPn7y3KvStg50n12pr+Zx rDolmoEa1Gu++R+5hMu5iz66kIvMw/D0NmtkWzEgBmqiUZHHHNO+jOIdQtojtDKE6bWg FSTzbtUeKpyykY3/g35oPC6UJAWwKP2X16sbbIZX42mvrplm4wDFPVxjR0VVJIPK3YW7 CZr2iucKr68eiIg76KMS22SnEC+eaaGGhjv2A+ZKZvG1A23BRqYfdtSc92yD70JYCyqw LfVQ== X-Gm-Message-State: ALoCoQlBbyaMM3XKgggx88qF3Qqsv3QsSOQXSppsebjJLeiHz5ihwhlATtWue993XUs6sVWfR76L X-Received: by 10.53.8.167 with SMTP id dl7mr5971337vdd.72.1405969251947; Mon, 21 Jul 2014 12:00:51 -0700 (PDT) MIME-Version: 1.0 Received: by 10.58.12.4 with HTTP; Mon, 21 Jul 2014 12:00:11 -0700 (PDT) From: Alexey Preobrazhensky Date: Mon, 21 Jul 2014 23:00:11 +0400 Message-ID: Subject: [PATCH] Support asan-fixed-shadow-offset in GCC To: GCC Patches Cc: Kostya Serebryany , Dmitry Vyukov , David Li , Yury Gribov , Andrey Ryabinin , Jakub Jelinek Hi all, This patch adds support for non-fixed shadow in asan stack instrumentation. It is required for Kernel AddressSanitizer, as the shadow offset is not known at the compile time, and the shadow may not be allocated during the early boot stages. This option is intended to be triggered by -fsanitize=kernel-address option, together with enabling instrumentation with calls. Bootstrapped®tested on x86_64. Codereview: https://codereview.appspot.com/118040043/ --- Alexey 2014-07-21 Yury Gribov Alexey Preobrazhensky New asan-fixed-shadow-offset parameter. gcc/ * asan.c (asan_emit_stack_protection): Add support for new parameter. * params.def: Define new parameter. * params.h: Likewise. gcc/testsuite/ * c-c++-common/asan/no-fixed-shadow-offset.c: New. Index: gcc/asan.c =================================================================== --- gcc/asan.c (revision 212896) +++ gcc/asan.c (working copy) @@ -979,6 +979,8 @@ HOST_WIDE_INT *offsets, tree *decls, int length) { rtx shadow_base, shadow_mem, ret, mem, orig_base, lab; + rtx shadow_start = NULL_RTX; + rtx skip_prologue_lab = NULL_RTX, skip_epilogue_lab = NULL_RTX; char buf[30]; unsigned char shadow_bytes[4]; HOST_WIDE_INT base_offset = offsets[length - 1]; @@ -1112,10 +1114,26 @@ shadow_base = expand_binop (Pmode, lshr_optab, base, GEN_INT (ASAN_SHADOW_SHIFT), NULL_RTX, 1, OPTAB_DIRECT); - shadow_base - = plus_constant (Pmode, shadow_base, - targetm.asan_shadow_offset () - + (base_align_bias >> ASAN_SHADOW_SHIFT)); + if (ASAN_FIXED_SHADOW_OFFSET) + { + shadow_base + = plus_constant (Pmode, shadow_base, + targetm.asan_shadow_offset () + + (base_align_bias >> ASAN_SHADOW_SHIFT)); + } + else + { + ret = init_one_libfunc ("__asan_get_shadow_ptr"); + shadow_start = gen_reg_rtx (ptr_mode); + emit_library_call_value (ret, shadow_start, LCT_NORMAL, ptr_mode, 0); + skip_prologue_lab = gen_label_rtx (); + emit_cmp_and_jump_insns (shadow_start, const0_rtx, EQ, NULL_RTX, VOIDmode, + 0, skip_prologue_lab, PROB_VERY_UNLIKELY); + shadow_base = expand_binop (Pmode, add_optab, shadow_base, shadow_start, + NULL_RTX, 1, OPTAB_DIRECT); + shadow_base = plus_constant (Pmode, shadow_base, + 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); @@ -1165,17 +1183,19 @@ } do_pending_stack_adjust (); + if (skip_prologue_lab) + emit_label (skip_prologue_lab); + /* Construct epilogue sequence. */ start_sequence (); - lab = NULL_RTX; if (use_after_return_class != -1) { - rtx lab2 = gen_label_rtx (); char c = (char) ASAN_STACK_MAGIC_USE_AFTER_RET; int very_likely = REG_BR_PROB_BASE - (REG_BR_PROB_BASE / 2000 - 1); + lab = gen_label_rtx (); emit_cmp_and_jump_insns (orig_base, base, EQ, NULL_RTX, - VOIDmode, 0, lab2, very_likely); + VOIDmode, 0, lab, very_likely); shadow_mem = gen_rtx_MEM (BLKmode, shadow_base); set_mem_alias_set (shadow_mem, asan_shadow_set); mem = gen_rtx_MEM (ptr_mode, base); @@ -1204,11 +1224,19 @@ TYPE_MODE (pointer_sized_int_node), orig_addr, ptr_mode); } - lab = gen_label_rtx (); - emit_jump (lab); - emit_label (lab2); + skip_epilogue_lab = gen_label_rtx (); + emit_jump (skip_epilogue_lab); + emit_label (lab); } + if (!ASAN_FIXED_SHADOW_OFFSET) + { + if (!skip_epilogue_lab) + skip_epilogue_lab = gen_label_rtx (); + emit_cmp_and_jump_insns (shadow_start, const0_rtx, EQ, NULL_RTX, VOIDmode, + 0, skip_epilogue_lab, PROB_VERY_UNLIKELY); + } + shadow_mem = gen_rtx_MEM (BLKmode, shadow_base); set_mem_alias_set (shadow_mem, asan_shadow_set); @@ -1245,9 +1273,10 @@ } do_pending_stack_adjust (); - if (lab) - emit_label (lab); + if (skip_epilogue_lab) + emit_label (skip_epilogue_lab); + ret = get_insns (); end_sequence (); return ret; Index: gcc/params.def =================================================================== --- gcc/params.def (revision 212896) +++ gcc/params.def (working copy) @@ -1081,6 +1081,11 @@ " in function becomes greater or equal than this threshold", 10000, 0, INT_MAX) +DEFPARAM (PARAM_ASAN_FIXED_SHADOW_OFFSET, + "asan-fixed-shadow-offset", + "Use fixed offset of shadow memory region", + 1, 0, 1) + DEFPARAM (PARAM_UNINIT_CONTROL_DEP_ATTEMPTS, "uninit-control-dep-attempts", "Maximum number of nested calls to search for control dependencies " Index: gcc/params.h =================================================================== --- gcc/params.h (revision 212896) +++ gcc/params.h (working copy) @@ -234,5 +234,7 @@ PARAM_VALUE (PARAM_ASAN_USE_AFTER_RETURN) #define ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD \ PARAM_VALUE (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD) +#define ASAN_FIXED_SHADOW_OFFSET \ + PARAM_VALUE (PARAM_ASAN_FIXED_SHADOW_OFFSET) #endif /* ! GCC_PARAMS_H */ Index: gcc/testsuite/c-c++-common/asan/no-fixed-shadow-offset.c =================================================================== --- gcc/testsuite/c-c++-common/asan/no-fixed-shadow-offset.c (revision 0) +++ gcc/testsuite/c-c++-common/asan/no-fixed-shadow-offset.c (working copy) @@ -0,0 +1,13 @@ +/* { dg-do assemble } */ +/* { dg-options "--param asan-fixed-shadow-offset=0 -save-temps" } */ + +extern void f(char *); + +int main() { + char buf[64]; + f(buf); + return 0; +} + +/* { dg-final { scan-assembler "__asan_get_shadow_ptr" } } */ +/* { dg-final { cleanup-saved-temps } } */ Index: libsanitizer/asan/asan_rtl.cc =================================================================== --- libsanitizer/asan/asan_rtl.cc (revision 212896) +++ libsanitizer/asan/asan_rtl.cc (working copy) @@ -430,6 +430,11 @@ } } +extern "C" +NOINLINE INTERFACE_ATTRIBUTE uptr __asan_get_shadow_ptr() { + return (uptr)SHADOW_OFFSET; +} + // Force the linker to keep the symbols for various ASan interface functions. // We want to keep those in the executable in order to let the instrumented // dynamic libraries access the symbol even if it is not used by the executable