Richard Earnshaw <richard.earns...@foss.arm.com> writes:

> On 09/12/2021 17:36, Andrea Corallo via Gcc-patches wrote:
>> Richard Earnshaw via Gcc-patches <gcc-patches@gcc.gnu.org> writes:
>> 
>>> On 28/10/2021 12:43, Tejas Belagod via Gcc-patches wrote:
>>>>
>>>>> -----Original Message-----
>>>>> From: Gcc-patches <gcc-patches-
>>>>> bounces+belagod=gcc.gnu....@gcc.gnu.org> On Behalf Of Tejas Belagod via
>>>>> Gcc-patches
>>>>> Sent: Friday, October 8, 2021 1:18 PM
>>>>> To: gcc-patches@gcc.gnu.org
>>>>> Subject: [Patch 5/7, Arm. GCC] Add pointer authentication for stack-
>>>>> unwinding runtime.
>>>>>
>>>>> Hi,
>>>>>
>>>>> This patch adds authentication for when the stack is unwound when an
>>>>> exception is taken.  All the changes here are done to the runtime code in
>>>>> libgcc's unwinder code for Arm target. All the changes are guarded under
>>>>> defined (__ARM_FEATURE_PAC_DEFAULT) and activates only if the +pacbti
>>>>> feature is switched on for the architecture. This means that switching on 
>>>>> the
>>>>> target feature via -march or -mcpu is sufficient and -mbranch-protection
>>>>> need not be enabled. This ensures that the unwinder is authenticated only 
>>>>> if
>>>>> the PACBTI instructions are available in the non-NOP space as it uses 
>>>>> AUTG.
>>>>> Just generating PAC/AUT instructions using -mbranch-protection will not
>>>>> enable authentication on the unwinder.
>>>>>
>>>>> Tested on arm-none-eabi. OK for trunk?
>>>>>
>>>>> 2021-10-04  Tejas Belagod  <tbela...@arm.com>
>>>>>
>>>>> gcc/ChangeLog:
>>>>>
>>>>>   * ginclude/unwind-arm-common.h (_Unwind_VRS_RegClass):
>>>>> Introduce
>>>>>   new pseudo register class _UVRSC_PAC.
>>>>>   * libgcc/config/arm/pr-support.c (__gnu_unwind_execute): Decode
>>>>>   exception opcode (0xb4) for saving RA_AUTH_CODE and
>>>>> authenticate
>>>>>   with AUTG if found.
>>>>>   * libgcc/config/arm/unwind-arm.c (struct pseudo_regs): New.
>>>>>   (phase1_vrs): Introduce new field to store pseudo-reg state.
>>>>>   (phase2_vrs): Likewise.
>>>>>   (_Unwind_VRS_Get): Load pseudo register state from virtual reg set.
>>>>>   (_Unwind_VRS_Set): Store pseudo register state to virtual reg set.
>>>>>   (_Unwind_VRS_Pop): Load pseudo register value from stack into
>>>>> VRS.
>>>> Rebased and respin based on reviews for previous patches.
>>>> This patch adds authentication for when the stack is unwound when
>>>> an exception is taken.  All the changes here are done to the runtime
>>>> code in libgcc's unwinder code for Arm target. All the changes are
>>>> guarded under defined (__ARM_FEATURE_PAUTH) and activates only
>>>> if the +pacbti feature is switched on for the architecture. This means
>>>> that switching on the target feature via -march or -mcpu is sufficient
>>>> and -mbranch-protection need not be enabled. This ensures that the
>>>> unwinder is authenticated only if the PACBTI instructions are available
>>>> in the non-NOP space as it uses AUTG. Just generating PAC/AUT instructions
>>>> using -mbranch-protection will not enable authentication on the unwinder.
>>>> 2021-10-25  Tejas Belagod  <tbela...@arm.com>
>>>> gcc/ChangeLog:
>>>>    * ginclude/unwind-arm-common.h (_Unwind_VRS_RegClass):
>>>> Introduce
>>>>    new pseudo register class _UVRSC_PAC.
>>>>    * libgcc/config/arm/pr-support.c (__gnu_unwind_execute): Decode
>>>>    exception opcode (0xb4) for saving RA_AUTH_CODE and authenticate
>>>>    with AUTG if found.
>>>>    * libgcc/config/arm/unwind-arm.c (struct pseudo_regs): New.
>>>>    (phase1_vrs): Introduce new field to store pseudo-reg state.
>>>>    (phase2_vrs): Likewise.
>>>>    (_Unwind_VRS_Get): Load pseudo register state from virtual reg set.
>>>>    (_Unwind_VRS_Set): Store pseudo register state to virtual reg set.
>>>>    (_Unwind_VRS_Pop): Load pseudo register value from stack into VRS.
>>>> Tested the following configurations, OK for trunk?
>>>> -mthumb/-march=armv8.1-m.main+pacbti/-mfloat-abi=soft
>>>> -marm/-march=armv7-a/-mfpu=vfpv3-d16/-mfloat-abi=softfp
>>>> mcmodel=small and tiny
>>>> aarch64-none-linux-gnu native test and bootstrap
>>>> Thanks,
>>>> Tejas.
>>>>
>> 
>>> I'd like to try to get rid of most of the ifdefs from this patch; at
>>> least, it shouldn't be using the ACLE PAUTH feature.  The unwinder
>>> should be able to cope with any unwind sequence thrown at it.
>>>
>>> Things are a little more complicated for pointer authentication,
>>> though, because some operations in the main code constructing the
>>> frame may be using architectural NOP instructions, while the unwinder
>>> cannot do the validation using only the architectural NOPs.
>>>
>>> So we need a fall-back: if the unwinder is built without the PAUTH
>>> feature it needs to unwind the pauth frames without the additional
>>> validation (but it still needs to be able to handle them).
>>>
>>> So the only remaining question is whether the additional support
>>> should only be enabled for M-profile targets, or whether we should
>>> just put this code into all builds of the unwinder.  I'm not sure I
>>> have a complete answer to that.  My inclination is to put it in
>>> unconditionally - we haven't had conditionals for any other optional
>>> architecture feature before.  If something similar is added for
>>> A/R-profiles, then either we will share the code exactly, or we'll end
>>> up with a different unwind code to use as a suitable discriminator.
>>>
>>> R.
>> Hi Richard,
>> thanks for reviewing.
>> The attached patch implements what I think we want.  That unwinders
>> is
>> always able to unwind the stack but will perform authentication only if
>> built with PACBTI support.
>> WDYT?
>> Thanks
>>    Andrea
>> 
>
>
> @@ -114,6 +115,22 @@ __gnu_unwind_execute (_Unwind_Context * context,
> __gnu_unwind_state * uws)
>        op = next_unwind_byte (uws);
>        if (op == CODE_FINISH)
>       {
> +       /* When we reach end, we have to authenticate R12 we just
> popped earlier.  */
> +       if (set_pac)
> +         {
> +#if defined(TARGET_HAVE_PACBTI)
> +           _uw sp;
> +           _uw lr;
> +           _uw pac;
> +           _Unwind_VRS_Get (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, &sp);
> +           _Unwind_VRS_Get (context, _UVRSC_CORE, R_LR, _UVRSD_UINT32, &lr);
> +           _Unwind_VRS_Get (context, _UVRSC_PAC, R_IP,
> +                            _UVRSD_UINT32, &pac);
> +           __asm__ __volatile__
> +             ("autg %0, %1, %2" : : "r"(pac), "r"(lr), "r"(sp) ;
> +#endif
> +         }
> +
>
> You would be better moving the ifdef outside of the 'if (set_pac)'
> clause, which becomes empty otherwise.  Also, I think a comment here
> is warranted that, while the check provides additional security
> against a corrupted unwind chain, it isn't essential for correct
> unwinding of an uncorrupted chain.
>
> Otherwise, this is ok.

Will do thanks.

  Andrea

Reply via email to