Hi all,

Ping? This new version changes both the middle-end and back-end part
so will need a review for both of those.

Best regards,

Thomas
On Wed, 29 Aug 2018 at 11:07, Thomas Preudhomme
<thomas.preudho...@linaro.org> wrote:
>
> Forgot another important change in ARM backend:
>
> The expander were causing one too many indirection which was what
> caused the test failure in glibc. The new expanders code skip the
> creation of a move from the memory reference of the guard's address to
> a register since this is done in the insn themselves. I think during
> the initial implementation of the first version of the patch I had
> issues with loading the address and used that to load the address. As
> can be seen from the absence of regression on the runtime stack
> protector test in glibc, this is now working properly, also confirmed
> by manual inspection of the code.
>
> I've attached the interdiff from previous version for reference.
>
> Best regards,
>
> Thomas
> On Wed, 29 Aug 2018 at 10:51, Thomas Preudhomme
> <thomas.preudho...@linaro.org> 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.
> > >     * 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