From patchwork Wed Jan 22 16:57:05 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Venkataramanan Kumar X-Patchwork-Id: 23551 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-gg0-f199.google.com (mail-gg0-f199.google.com [209.85.161.199]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 6FEEC203C6 for ; Wed, 22 Jan 2014 16:57:08 +0000 (UTC) Received: by mail-gg0-f199.google.com with SMTP id n5sf15049393ggj.10 for ; Wed, 22 Jan 2014 08:57:07 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:mime-version:date:message-id :subject:from:to:x-original-sender:x-original-authentication-results :precedence:mailing-list:list-id:list-post:list-help:list-archive :list-unsubscribe:content-type; bh=a6rqjQ8YD0o+InFzBRt4Fq5oHbI/NJbu8MlbIHFWYWw=; b=Z1+aVr4GcVdLEVS8AGe5imjYBCD1aI+7/kSWUAvsSZLx1zxZb6RS4SSZAVnHwKqCjY S3NL6nWI+Sp9ZgHkMNILfqMhm9oHkUPewTyERLsrCzg05rU7h/Gy8fIgGQM5ihh3AYVS GYMsxbCuPrbREY5nztKMDSKr8vTC+IMHq40ICIBAWQvGCfqCxY6DiuP1+aRfIyFOSsih 4S0BS15WoTocGM7YzyVElv3mW/vVLbT1zNCJF/P+zLhPGHfGTDNSW6u3eZ25pPbNOfa8 mZd9D98gC3Mbc9tyTSH76Ker/bCLxPMa0v3TD3qqsHkV+Go14Fw1cdug33K5gzsEuxtx mDTg== X-Gm-Message-State: ALoCoQkT3Pg+loElMXPQomjAlUjp2wkmpGYdpp2NMSKIlURIskBDSnsbXEicw3TOHGCghso6SdL9 X-Received: by 10.236.26.209 with SMTP id c57mr804297yha.45.1390409827606; Wed, 22 Jan 2014 08:57:07 -0800 (PST) X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.97.38 with SMTP id dx6ls98148qeb.68.gmail; Wed, 22 Jan 2014 08:57:07 -0800 (PST) X-Received: by 10.58.201.169 with SMTP id kb9mr515491vec.42.1390409827487; Wed, 22 Jan 2014 08:57:07 -0800 (PST) Received: from mail-vc0-f175.google.com (mail-vc0-f175.google.com [209.85.220.175]) by mx.google.com with ESMTPS id vx3si4892662vcb.28.2014.01.22.08.57.07 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 22 Jan 2014 08:57:07 -0800 (PST) Received-SPF: neutral (google.com: 209.85.220.175 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.220.175; Received: by mail-vc0-f175.google.com with SMTP id ij19so375038vcb.20 for ; Wed, 22 Jan 2014 08:57:07 -0800 (PST) X-Received: by 10.58.161.227 with SMTP id xv3mr1538111veb.31.1390409827405; Wed, 22 Jan 2014 08:57:07 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.220.174.196 with SMTP id u4csp198180vcz; Wed, 22 Jan 2014 08:57:06 -0800 (PST) X-Received: by 10.229.249.66 with SMTP id mj2mr4250244qcb.4.1390409825806; Wed, 22 Jan 2014 08:57:05 -0800 (PST) Received: from mail-qc0-f171.google.com (mail-qc0-f171.google.com [209.85.216.171]) by mx.google.com with ESMTPS id e5si3824657qab.97.2014.01.22.08.57.05 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 22 Jan 2014 08:57:05 -0800 (PST) Received-SPF: neutral (google.com: 209.85.216.171 is neither permitted nor denied by best guess record for domain of venkataramanan.kumar@linaro.org) client-ip=209.85.216.171; Received: by mail-qc0-f171.google.com with SMTP id n7so840236qcx.2 for ; Wed, 22 Jan 2014 08:57:05 -0800 (PST) MIME-Version: 1.0 X-Received: by 10.140.95.151 with SMTP id i23mr4024311qge.20.1390409825621; Wed, 22 Jan 2014 08:57:05 -0800 (PST) Received: by 10.140.83.19 with HTTP; Wed, 22 Jan 2014 08:57:05 -0800 (PST) Date: Wed, 22 Jan 2014 22:27:05 +0530 Message-ID: Subject: [RFC] [PATCH, AARCH64] : Using standard patterns for stack protection. From: Venkataramanan Kumar To: Marcus Shawcroft , Marcus Shawcroft , "gcc-patches@gcc.gnu.org" , Patch Tracking X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: venkataramanan.kumar@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.220.175 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Hi Marcus, After we changed the frame growing direction (downwards) in Aarch64, the back-end now generates stack smashing set and test based on generic code available in GCC. But most of the ports (i386, spu, rs6000, s390, sh, sparc, tilepro and tilegx) define machine descriptions using standard pattern names ‘stack_protect_set’ and ‘stack_protect_test’. This is done for both TLS model as well as global variable based stack guard model. Also all these ports in their machine descriptions, have cleared the register that loaded the canary value using an additional instruction. (GCC internals) ‘stack_protect_set’ This pattern, if defined, moves a ptr_mode value from the memory in operand 1 to the memory in operand 0 without leaving the value in a register afterward. This is to avoid leaking the value some place that an attacker might use to rewrite the stack guard slot after having clobbered it. If this pattern is not defined, then a plain move pattern is generated. (GCC internals) I believe this is done for extra security. Also each target can control the way of clearing the register that loaded the canary value. In the attached patch, I have written machine descriptions patterns for stack_protect_set and stack_protect_test for Aarch64. Also I am clearing the register by moving 0 to the register while setting the stack and using "eor" instruction while testing the stack. However this generates un-optimal code when compared to generic GCC code. While setting up stack canary , Generic code adrp x19, __stack_chk_guard ldr x1, [x19,#:lo12:__stack_chk_guard] str x1, [x29,40] Patch adrp x19, __stack_chk_guard add x1, x19, :lo12:__stack_chk_guard ldr x2, [x1] str x1, [x29,40] mov x2, 0 while testing stack canary generic code ldr x1, [x29,40] ldr x0, [x19,#:lo12:__stack_chk_guard] cmp x1, x0 bne .L7 patch add x19, x19, :lo12:__stack_chk_guard ldr x1, [x29,40] ldr x0, [x19] eor x0, x1, x0 cbnz x0, .L7 Please let me know if this change is fine for Aarch64. 2014-01-22 Venkataramanan Kumar * config/aarch64/aarch64.md (stack_protect_set, stack_protect_test) (stack_protect_set_, stack_protect_test_): Add machine descriptions for Stack Smashing Protector. 2014-01-22 Venkataramanan Kumar * lib/target-supports.exp (check_effective_target_stack_protection): New procedure. * g++.dg/fstack-protector-strong.C: Add target check for stack protection. * gcc.dg/fstack-protector-strong.c: Likewise. regards, Venkat. Index: gcc/config/aarch64/aarch64.md =================================================================== --- gcc/config/aarch64/aarch64.md (revision 206874) +++ gcc/config/aarch64/aarch64.md (working copy) @@ -99,6 +99,8 @@ UNSPEC_TLSDESC UNSPEC_USHL_2S UNSPEC_VSTRUCTDUMMY + UNSPEC_SP_SET + UNSPEC_SP_TEST ]) (define_c_enum "unspecv" [ @@ -3631,6 +3633,65 @@ DONE; }) +;; Named patterns for stack smashing protection. +(define_expand "stack_protect_set" + [(match_operand 0 "memory_operand") + (match_operand 1 "memory_operand")] + "" +{ + enum machine_mode mode = GET_MODE (operands[0]); + + emit_insn ((mode == DImode + ? gen_stack_protect_set_di + : gen_stack_protect_set_si) (operands[0], operands[1])); + DONE; +}) + +(define_insn "stack_protect_set_" + [(set (match_operand:PTR 0 "memory_operand" "=m") + (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")] + UNSPEC_SP_SET)) + (set (match_scratch:PTR 2 "=&r") (const_int 0))] + "" + "ldr\\t%x2, %1\;str\\t%x2, %0\;mov\t%x2,0" + [(set_attr "length" "12")]) + +(define_expand "stack_protect_test" + [(match_operand 0 "memory_operand") + (match_operand 1 "memory_operand") + (match_operand 2)] + "" +{ + + rtx result = gen_reg_rtx (Pmode); + + enum machine_mode mode = GET_MODE (operands[0]); + + emit_insn ((mode == DImode + ? gen_stack_protect_test_di + : gen_stack_protect_test_si) (result, + operands[0], + operands[1])); + + if (mode == DImode) + emit_jump_insn (gen_cbranchdi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx), + result, const0_rtx, operands[2])); + else + emit_jump_insn (gen_cbranchsi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx), + result, const0_rtx, operands[2])); + DONE; +}) + +(define_insn "stack_protect_test_" + [(set (match_operand:PTR 0 "register_operand") + (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m") + (match_operand:PTR 2 "memory_operand" "m")] + UNSPEC_SP_TEST)) + (clobber (match_scratch:PTR 3 "=&r"))] + "" + "ldr\t%x3, %x1\;ldr\t%x0, %x2\;eor\t%x0, %x3, %x0" + [(set_attr "length" "12")]) + ;; AdvSIMD Stuff (include "aarch64-simd.md") Index: gcc/testsuite/g++.dg/fstack-protector-strong.C =================================================================== --- gcc/testsuite/g++.dg/fstack-protector-strong.C (revision 206874) +++ gcc/testsuite/g++.dg/fstack-protector-strong.C (working copy) @@ -1,6 +1,6 @@ /* Test that stack protection is done on chosen functions. */ -/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ +/* { dg-do compile { target stack_protection } } */ /* { dg-options "-O2 -fstack-protector-strong" } */ class A Index: gcc/testsuite/gcc.dg/fstack-protector-strong.c =================================================================== --- gcc/testsuite/gcc.dg/fstack-protector-strong.c (revision 206874) +++ gcc/testsuite/gcc.dg/fstack-protector-strong.c (working copy) @@ -1,6 +1,6 @@ /* Test that stack protection is done on chosen functions. */ -/* { dg-do compile { target i?86-*-* x86_64-*-* rs6000-*-* s390x-*-* } } */ +/* { dg-do compile { target stack_protection } } */ /* { dg-options "-O2 -fstack-protector-strong" } */ #include Index: gcc/testsuite/lib/target-supports.exp =================================================================== --- gcc/testsuite/lib/target-supports.exp (revision 206874) +++ gcc/testsuite/lib/target-supports.exp (working copy) @@ -810,6 +810,17 @@ } "-fstack-protector"] } +# Return 1 the target supports stack protection. +proc check_effective_target_stack_protection { } { + if { [istarget i?86-*-*] + || [istarget x86_64-*-*] + || [istarget aarch64-*-*] + || [istarget s390x-*-*] } { + return 1; + } + return 0 +} + # Return 1 if compilation with -freorder-blocks-and-partition is error-free # for trivial code, 0 otherwise.