[libcxx-commits] [PATCH] D128522: [libunwind, EHABI, ARM] Fix get/set of RA_AUTH_CODE.

Simon Tatham via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Fri Jun 24 06:21:26 PDT 2022

simon_tatham created this revision.
simon_tatham added reviewers: stuij, momchil.velikov, vhscampos, MaskRay, danielkiss, mstorsjo.
Herald added subscribers: libcxx-commits, StephenFan, kristof.beyls.
Herald added projects: libunwind, All.
Herald added a reviewer: libunwind.
simon_tatham requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

According to EHABI32 ยง8.5.2, the PAC for the return address of a
function described in an exception table is supposed to be addressed
in the _Unwind_VRS_{Get,Set} API by setting regclass=_UVRSC_PSEUDO and
regno=0. (The space of 'regno' values is independent for each
regclass, and for _UVRSC_PSEUDO, there is only one valid regno so far.)

That is indeed what libunwind's _Unwind_VRS_{Get,Set} functions expect
to receive. But at two call sites, the wrong values are passed in:
regno is being set to UNW_ARM_RA_AUTH_CODE (0x8F) instead of 0, and in
one case, regclass is _UVRSC_CORE instead of _UVRSC_PSEUDO.

As a result, those calls to _Unwind_VRS_{Get,Set} return
_UVRSR_FAILED, which their callers ignore. So if you compile in the
AUTG instruction that actually validates the PAC, it will try to
validate what's effectively an uninitialised register as an
authentication code, and trigger a CPU fault even on correct exception

  rG LLVM Github Monorepo



Index: libunwind/src/Unwind-EHABI.cpp
--- libunwind/src/Unwind-EHABI.cpp
+++ libunwind/src/Unwind-EHABI.cpp
@@ -432,8 +432,7 @@
       uint32_t sp;
       uint32_t pac;
       _Unwind_VRS_Get(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, &sp);
-      _Unwind_VRS_Get(context, _UVRSC_PSEUDO, UNW_ARM_RA_AUTH_CODE,
-                      _UVRSD_UINT32, &pac);
+      _Unwind_VRS_Get(context, _UVRSC_PSEUDO, 0, _UVRSD_UINT32, &pac);
       __asm__ __volatile__("autg %0, %1, %2" : : "r"(pac), "r"(lr), "r"(sp) :);
@@ -1138,8 +1137,7 @@
       uint32_t pac = *sp++;
       _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, &sp);
-      return _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_RA_AUTH_CODE,
-                             _UVRSD_UINT32, &pac);
+      return _Unwind_VRS_Set(context, _UVRSC_PSEUDO, 0, _UVRSD_UINT32, &pac);
   _LIBUNWIND_ABORT("unsupported register class");

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D128522.439725.patch
Type: text/x-patch
Size: 1002 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20220624/f25d75ef/attachment.bin>

More information about the libcxx-commits mailing list