Ping?

Best regards,

Thomas
On Fri, 26 Oct 2018 at 22:41, Thomas Preudhomme
<thomas.preudho...@linaro.org> wrote:
>
> Hi,
>
> Please find updated patch to fix PR85434: spilling of stack protector
> guard's address on ARM. Quite a few changes have been made to the ARM
> part since last round of review so I think it makes more sense to
> review it anew. Ran bootstrap + regression testsuite + glibc build +
> glibc regression testsuite for Arm and Thumb-2 and bootstrap +
> regression testsuite for Thumb-1. GCC's regression testsuite was run
> in 3 configurations in all those cases:
>
> - default configuration (no RUNTESTFLAGS)
> - with -fstack-protector-all
> - with -fPIC -fstack-protector-all (to exercise both codepath in stack
> protector's split code)
>
> None of this show any regression beyond some new scan fail with
> -fstack-protector-all or -fPIC due to unexpected code sequence for the
> testcases concerned and some guality swing due to less optimization
> with new stack protector on.
>
> Patch description and ChangeLog below.
>
> In case of high register pressure in PIC mode, address of the stack
> protector's guard can be spilled on ARM targets as shown in PR85434,
> thus allowing an attacker to control what the canary would be compared
> against. ARM does lack stack_protect_set and stack_protect_test insn
> patterns, defining them does not help as the address is expanded
> regularly and the patterns only deal with the copy and test of the
> guard with the canary.
>
> This problem does not occur for x86 targets because the PIC access and
> the test can be done in the same instruction. Aarch64 is exempt too
> because PIC access insn pattern are mov of UNSPEC which prevents it from
> the second access in the epilogue being CSEd in cse_local pass with the
> first access in the prologue.
>
> The approach followed here is to create new "combined" set and test
> standard pattern names that take the unexpanded guard and do the set or
> test. This allows the target to use an opaque pattern (eg. using UNSPEC)
> to hide the individual instructions being generated to the compiler and
> split the pattern into generic load, compare and branch instruction
> after register allocator, therefore avoiding any spilling. This is here
> implemented for the ARM targets. For targets not implementing these new
> standard pattern names, the existing stack_protect_set and
> stack_protect_test pattern names are used.
>
> To be able to split PIC access after register allocation, the functions
> had to be augmented to force a new PIC register load and to control
> which register it loads into. This is because sharing the PIC register
> between prologue and epilogue could lead to spilling due to CSE again
> which an attacker could use to control what the canary gets compared
> against.
>
> ChangeLog entries are as follows:
>
> *** gcc/ChangeLog ***
>
> 2018-10-26  Thomas Preud'homme  <thomas.preudho...@linaro.org>
>
> * target-insns.def (stack_protect_combined_set): Define new standard
> pattern name.
> (stack_protect_combined_test): Likewise.
> * cfgexpand.c (stack_protect_prologue): Try new
> stack_protect_combined_set pattern first.
> * function.c (stack_protect_epilogue): Try new
> stack_protect_combined_test pattern first.
> * config/arm/arm.c (require_pic_register): Add pic_reg and compute_now
> parameters to control which register to use as PIC register and force
> reloading PIC register respectively.  Insert in the stream of insns if
> possible.
> (legitimize_pic_address): Expose above new parameters in prototype and
> adapt recursive calls accordingly.  Use pic_reg if non null instead of
> cached one.
> (arm_load_pic_register): Add pic_reg parameter and use it if non null.
> (arm_legitimize_address): Adapt to new legitimize_pic_address
> prototype.
> (thumb_legitimize_address): Likewise.
> (arm_emit_call_insn): Adapt to require_pic_register prototype change.
> (arm_expand_prologue): Adapt to arm_load_pic_register prototype change.
> (thumb1_expand_prologue): Likewise.
> * config/arm/arm-protos.h (legitimize_pic_address): Adapt to prototype
> change.
> (arm_load_pic_register): Likewise.
> * config/arm/predicated.md (guard_addr_operand): New predicate.
> (guard_operand): New predicate.
> * config/arm/arm.md (movsi expander): Adapt to legitimize_pic_address
> prototype change.
> (builtin_setjmp_receiver expander): Adapt to thumb1_expand_prologue
> prototype change.
> (stack_protect_combined_set): New expander..
> (stack_protect_combined_set_insn): New insn_and_split pattern.
> (stack_protect_set_insn): New insn pattern.
> (stack_protect_combined_test): New expander.
> (stack_protect_combined_test_insn): New insn_and_split pattern.
> (arm_stack_protect_test_insn): New insn pattern.
> * config/arm/thumb1.md (thumb1_stack_protect_test_insn): New insn pattern.
> * config/arm/unspecs.md (UNSPEC_SP_SET): New unspec.
> (UNSPEC_SP_TEST): Likewise.
> * doc/md.texi (stack_protect_combined_set): Document new standard
> pattern name.
> (stack_protect_set): Clarify that the operand for guard's address is
> legal.
> (stack_protect_combined_test): Document new standard pattern name.
> (stack_protect_test): Clarify that the operand for guard's address is
> legal.
>
> *** gcc/testsuite/ChangeLog ***
>
> 2018-07-05  Thomas Preud'homme  <thomas.preudho...@linaro.org>
>
> * gcc.target/arm/pr85434.c: New test.
>
> Is this ok for trunk?
>
> Best regards,
>
> Thomas
> On Thu, 25 Oct 2018 at 15:54, Thomas Preudhomme
> <thomas.preudho...@linaro.org> wrote:
> >
> > Good thing I did, found a missing earlyclobber in the process.
> > Rerunning all tests again.
> >
> > Best regards,
> >
> > Thomas
> > On Wed, 24 Oct 2018 at 10:13, Thomas Preudhomme
> > <thomas.preudho...@linaro.org> wrote:
> > >
> > > Please hold on for the reviews, found a small improvement that could
> > > be done. Am testing it right now, should have something by tonight or
> > > tomorrow.
> > >
> > > Best regards,
> > >
> > > Thomas
> > > On Tue, 23 Oct 2018 at 13:35, Thomas Preudhomme
> > > <thomas.preudho...@linaro.org> wrote:
> > > >
> > > > [Removing Jeff Law since middle end code hasn't changed]
> > > >
> > > > Hi,
> > > >
> > > > Given how memory operand are reloaded even with an X constraint, I've
> > > > reworked the patch for the combined set and combined test instruction
> > > > ot keep the mem out of the match_operand and used an expander to
> > > > generate the right instruction pattern. I've also fixed some
> > > > longstanding issues with the patch when flag_pic is true and with
> > > > constraints for Thumb-1 that I hadn't noticed before due to using
> > > > dg-cmp-results in conjunction with test_summary which does not show
> > > > NA->FAIL (see [1]).
> > > >
> > > > All in all, I think the Arm code would do with a fresh review rather
> > > > than looking at the changes since last posted version. (unchanged)
> > > > ChangeLog entries are as follows:
> > > >
> > > > *** gcc/ChangeLog ***
> > > >
> > > > 2018-08-09  Thomas Preud'homme  <thomas.preudho...@linaro.org>
> > > >
> > > >     * target-insns.def (stack_protect_combined_set): Define new standard
> > > >     pattern name.
> > > >     (stack_protect_combined_test): Likewise.
> > > >     * cfgexpand.c (stack_protect_prologue): Try new
> > > >     stack_protect_combined_set pattern first.
> > > >     * function.c (stack_protect_epilogue): Try new
> > > >     stack_protect_combined_test pattern first.
> > > >     * config/arm/arm.c (require_pic_register): Add pic_reg and 
> > > > compute_now
> > > >     parameters to control which register to use as PIC register and 
> > > > force
> > > >     reloading PIC register respectively.  Insert in the stream of insns 
> > > > if
> > > >     possible.
> > > >     (legitimize_pic_address): Expose above new parameters in prototype 
> > > > and
> > > >     adapt recursive calls accordingly.  Use pic_reg if non null instead 
> > > > of
> > > >     cached one.
> > > >     (arm_load_pic_register): Add pic_reg parameter and use it if non 
> > > > null.
> > > >     (arm_legitimize_address): Adapt to new legitimize_pic_address
> > > >     prototype.
> > > >     (thumb_legitimize_address): Likewise.
> > > >     (arm_emit_call_insn): Adapt to require_pic_register prototype 
> > > > change.
> > > >     (arm_expand_prologue): Adapt to arm_load_pic_register prototype 
> > > > change.
> > > >     (thumb1_expand_prologue): Likewise.
> > > >     * config/arm/arm-protos.h (legitimize_pic_address): Adapt to 
> > > > prototype
> > > >     change.
> > > >     (arm_load_pic_register): Likewise.
> > > >     * config/arm/predicated.md (guard_addr_operand): New predicate.
> > > >     (guard_operand): New predicate.
> > > >     * config/arm/arm.md (movsi expander): Adapt to 
> > > > legitimize_pic_address
> > > >     prototype change.
> > > >     (builtin_setjmp_receiver expander): Adapt to thumb1_expand_prologue
> > > >     prototype change.
> > > >     (stack_protect_combined_set): New expander..
> > > >     (stack_protect_combined_set_insn): New insn_and_split pattern.
> > > >     (stack_protect_set_insn): New insn pattern.
> > > >     (stack_protect_combined_test): New expander.
> > > >     (stack_protect_combined_test_insn): New insn_and_split pattern.
> > > >     (stack_protect_test_insn): New insn pattern.
> > > >     * config/arm/unspecs.md (UNSPEC_SP_SET): New unspec.
> > > >     (UNSPEC_SP_TEST): Likewise.
> > > >     * doc/md.texi (stack_protect_combined_set): Document new standard
> > > >     pattern name.
> > > >     (stack_protect_set): Clarify that the operand for guard's address is
> > > >     legal.
> > > >     (stack_protect_combined_test): Document new standard pattern name.
> > > >     (stack_protect_test): Clarify that the operand for guard's address 
> > > > is
> > > >     legal.
> > > >
> > > > *** gcc/testsuite/ChangeLog ***
> > > >
> > > > 2018-07-05  Thomas Preud'homme  <thomas.preudho...@linaro.org>
> > > >
> > > >     * gcc.target/arm/pr85434.c: New test.
> > > >
> > > > Testing: Bootstrap and regression testing for Arm, Thumb-1 and Thumb-2
> > > > with (i) default flags, (ii) an extra -fstack-protect-all and (iii)
> > > > -fPIC -fstack-protect-all. A glibc build and testsuite run was also
> > > > performed for Arm and Thumb-2. Default flags show no regression and
> > > > the other runs have some expected scan-assembler failing (due to stack
> > > > protector or fPIC code sequence), as well as guality fail (due to less
> > > > optimized code with the new stack protector code) and some execution
> > > > failures in sibcall-9 and sibcall-10 under -fPIC -fstack-protector-all
> > > > due to the PIC sequence for the global variable making the frame
> > > > layout different for the 2 functions (these become PASS if making the
> > > > global variable static).
> > > >
> > > > Is this ok for trunk?
> > > >
> > > > Best regards,
> > > >
> > > > Thomas
> > > >
> > > > [1] https://gcc.gnu.org/ml/gcc-patches/2018-10/msg01412.html
> > > >
> > > >
> > > > On Tue, 25 Sep 2018 at 17:10, Kyrill Tkachov
> > > > <kyrylo.tkac...@foss.arm.com> wrote:
> > > > >
> > > > > Hi Thomas,
> > > > >
> > > > > On 29/08/18 10:51, Thomas Preudhomme wrote:
> > > > > > Resend hopefully without HTML this time.
> > > > > >
> > > > > > On Wed, 29 Aug 2018 at 10:49, Thomas Preudhomme
> > > > > > <thomas.preudho...@linaro.org> wrote:
> > > > > >> Hi,
> > > > > >>
> > > > > >> I've reworked the patch fixing PR85434 (spilling of stack 
> > > > > >> protector guard's address on ARM) to address the testsuite 
> > > > > >> regression on powerpc and x86 as well as glibc testsuite 
> > > > > >> regression on ARM. Issues were due to unconditionally attempting 
> > > > > >> to generate the new patterns. The code now tests if there is a 
> > > > > >> pattern for them for the target before generating them. In the ARM 
> > > > > >> side of the patch, I've also added a more specific predicate for 
> > > > > >> the new patterns. The new patch is found below.
> > > > > >>
> > > > > >>
> > > > > >> In case of high register pressure in PIC mode, address of the stack
> > > > > >> protector's guard can be spilled on ARM targets as shown in 
> > > > > >> PR85434,
> > > > > >> thus allowing an attacker to control what the canary would be 
> > > > > >> compared
> > > > > >> against. ARM does lack stack_protect_set and stack_protect_test 
> > > > > >> insn
> > > > > >> patterns, defining them does not help as the address is expanded
> > > > > >> regularly and the patterns only deal with the copy and test of the
> > > > > >> guard with the canary.
> > > > > >>
> > > > > >> This problem does not occur for x86 targets because the PIC access 
> > > > > >> and
> > > > > >> the test can be done in the same instruction. Aarch64 is exempt too
> > > > > >> because PIC access insn pattern are mov of UNSPEC which prevents 
> > > > > >> it from
> > > > > >> the second access in the epilogue being CSEd in cse_local pass 
> > > > > >> with the
> > > > > >> first access in the prologue.
> > > > > >>
> > > > > >> The approach followed here is to create new "combined" set and test
> > > > > >> standard pattern names that take the unexpanded guard and do the 
> > > > > >> set or
> > > > > >> test. This allows the target to use an opaque pattern (eg. using 
> > > > > >> UNSPEC)
> > > > > >> to hide the individual instructions being generated to the 
> > > > > >> compiler and
> > > > > >> split the pattern into generic load, compare and branch instruction
> > > > > >> after register allocator, therefore avoiding any spilling. This is 
> > > > > >> here
> > > > > >> implemented for the ARM targets. For targets not implementing 
> > > > > >> these new
> > > > > >> standard pattern names, the existing stack_protect_set and
> > > > > >> stack_protect_test pattern names are used.
> > > > > >>
> > > > > >> To be able to split PIC access after register allocation, the 
> > > > > >> functions
> > > > > >> had to be augmented to force a new PIC register load and to control
> > > > > >> which register it loads into. This is because sharing the PIC 
> > > > > >> register
> > > > > >> between prologue and epilogue could lead to spilling due to CSE 
> > > > > >> again
> > > > > >> which an attacker could use to control what the canary gets 
> > > > > >> compared
> > > > > >> against.
> > > > > >>
> > > > > >> ChangeLog entries are as follows:
> > > > > >>
> > > > > >> *** gcc/ChangeLog ***
> > > > > >>
> > > > > >> 2018-08-09  Thomas Preud'homme  <thomas.preudho...@linaro.org>
> > > > > >>
> > > > > >>      * target-insns.def (stack_protect_combined_set): Define new 
> > > > > >> standard
> > > > > >>      pattern name.
> > > > > >>      (stack_protect_combined_test): Likewise.
> > > > > >>      * cfgexpand.c (stack_protect_prologue): Try new
> > > > > >>      stack_protect_combined_set pattern first.
> > > > > >>      * function.c (stack_protect_epilogue): Try new
> > > > > >>      stack_protect_combined_test pattern first.
> > > > > >>      * config/arm/arm.c (require_pic_register): Add pic_reg and 
> > > > > >> compute_now
> > > > > >>      parameters to control which register to use as PIC register 
> > > > > >> and force
> > > > > >>      reloading PIC register respectively.  Insert in the stream of 
> > > > > >> insns if
> > > > > >>      possible.
> > > > > >>      (legitimize_pic_address): Expose above new parameters in 
> > > > > >> prototype and
> > > > > >>      adapt recursive calls accordingly.
> > > > > >>      (arm_legitimize_address): Adapt to new legitimize_pic_address
> > > > > >>      prototype.
> > > > > >>      (thumb_legitimize_address): Likewise.
> > > > > >>      (arm_emit_call_insn): Adapt to new require_pic_register 
> > > > > >> prototype.
> > > > > >>      * config/arm/arm-protos.h (legitimize_pic_address): Adapt to 
> > > > > >> prototype
> > > > > >>      change.
> > > > > >>      * config/arm/predicated.md (guard_operand): New predicate.
> > > > >
> > > > > Typo, predicates.md is the filename.
> > > > >
> > > > > Looks ok to me otherwise.
> > > > > Thank you for your patience.
> > > > >
> > > > > Kyrill
> > > > >
> > > > > >>      * config/arm/arm.md (movsi expander): Adapt to 
> > > > > >> legitimize_pic_address
> > > > > >>      prototype change.
> > > > > >>      (stack_protect_combined_set): New insn_and_split pattern.
> > > > > >>      (stack_protect_set): New insn pattern.
> > > > > >>      (stack_protect_combined_test): New insn_and_split pattern.
> > > > > >>      (stack_protect_test): New insn pattern.
> > > > > >>      * config/arm/unspecs.md (UNSPEC_SP_SET): New unspec.
> > > > > >>      (UNSPEC_SP_TEST): Likewise.
> > > > > >>      * doc/md.texi (stack_protect_combined_set): Document new 
> > > > > >> standard
> > > > > >>      pattern name.
> > > > > >>      (stack_protect_set): Clarify that the operand for guard's 
> > > > > >> address is
> > > > > >>      legal.
> > > > > >>      (stack_protect_combined_test): Document new standard pattern 
> > > > > >> name.
> > > > > >>      (stack_protect_test): Clarify that the operand for guard's 
> > > > > >> address is
> > > > > >>      legal.
> > > > > >>
> > > > > >> *** gcc/testsuite/ChangeLog ***
> > > > > >>
> > > > > >> 2018-07-05  Thomas Preud'homme  <thomas.preudho...@linaro.org>
> > > > > >>
> > > > > >>      * gcc.target/arm/pr85434.c: New test.
> > > > >
> > > > > >>
> > > > > >> Testing:
> > > > > >>
> > > > > >> native x86_64: bootstrap + testsuite -> no regression, can see 
> > > > > >> failures with previous version of patch but not with new version
> > > > > >> native powerpc64: bootstrap + testsuite -> no regression, can see 
> > > > > >> failures from pr86834 with previous version of patch but not with 
> > > > > >> new version
> > > > > >> cross ARM Linux: build + testsuite -> no regression
> > > > > >> native ARM Thumb-2: bootstrap + testsuite + glibc build + glibc 
> > > > > >> test -> no regression
> > > > > >> native ARM Arm: bootstrap + testsuite + glibc build + glibc test 
> > > > > >> -> no regression
> > > > > >> Aarch64: bootstrap + testsuite + glibc build + glibc test-> no 
> > > > > >> regression
> > > > > >>
> > > > > >> Is this ok for trunk?
> > > > > >>
> > > > > >> Best regards,
> > > > > >>
> > > > > >> Thomas
> > > > >

Reply via email to