Skip to content

Commit

Permalink
fixup! [libunwind] Support rtld-c18n as the runtime linker.
Browse files Browse the repository at this point in the history
  • Loading branch information
dpgao committed Apr 17, 2024
1 parent facade9 commit bfc94ec
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 46 deletions.
16 changes: 7 additions & 9 deletions libunwind/src/CompartmentInfo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,15 @@ class _LIBUNWIND_HIDDEN CompartmentInfo {
static const uintcap_t kInvalidRCSP = (uintcap_t)0;
// Per-architecture trusted stack frame layout.
#if defined(_LIBUNWIND_TARGET_AARCH64)
static const uint32_t kNewSPOffset = 48;
static const uint32_t kNextOffset = 32;
static const uint32_t kNewSPOffset = 12 * sizeof(void *);
static const uint32_t kNextOffset = 14 * sizeof(void *);
static const uint32_t kFPOffset = 0;
static const uint32_t kCalleeSavedOffset = 80;
static const uint32_t kCalleeSavedOffset = 2 * sizeof(void *);
static const uint32_t kCalleeSavedCount = 10;
static const uint32_t kCalleeSavedSize = 16;
static const uint32_t kReturnAddressOffset = 40;
static const uint32_t kPCOffset = 16;
// kCalleeSavedCount - 1 because kCalleeSavedOffset is the first one.
static const uint32_t kTrustedFrameSize =
kCalleeSavedOffset + (kCalleeSavedCount - 1) * kCalleeSavedSize;
static const uint32_t kCalleeSavedSize = sizeof(void *);
static const uint32_t kReturnAddressOffset = 15 * sizeof(void *) + 8;
static const uint32_t kPCOffset = sizeof(void *);
static const uint32_t kTrustedFrameSize = 16 * sizeof(void *);
#endif // _LIBUNWIND_TARGET_AARCH64
#endif // __CHERI_PURE_CAPABILITY__
};
Expand Down
45 changes: 8 additions & 37 deletions libunwind/src/DwarfInstructions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ class DwarfInstructions {
R &newRegisters,
CompartmentInfo &CI,
uintcap_t sealer);
static bool isEndOfExecutiveStack(uintcap_t csp, CompartmentInfo &CI);
static bool isTrampoline(uintcap_t ecsp, A &addressSpace, CompartmentInfo &CI,
uintcap_t returnAddress);
#endif
Expand Down Expand Up @@ -305,8 +304,7 @@ uintptr_t DwarfInstructions<A, R>::restoreRegistersFromSandbox(
assert(__builtin_cheri_tag_get((void *)csp) &&
"Executive stack should be tagged!");
// Derive the new executive CSP
ptraddr_t nextCSPAddr = addressSpace.get64(csp + CI.kNextOffset);
uintcap_t nextCSP = __builtin_cheri_address_set(csp, nextCSPAddr);
uintcap_t nextCSP = addressSpace.getCapability(csp + CI.kNextOffset);
#ifdef _LIBUNWIND_SANDBOX_HARDENED
// Seal ECSP
nextCSP = __builtin_cheri_seal(nextCSP, sealer);
Expand Down Expand Up @@ -338,27 +336,16 @@ uintptr_t DwarfInstructions<A, R>::restoreRegistersFromSandbox(
return addressSpace.getCapability(csp + CI.kPCOffset);
}

template <typename A, typename R>
bool DwarfInstructions<A, R>::isEndOfExecutiveStack(uintcap_t csp,
CompartmentInfo &CI) {
CHERI_DBG("isEndOfExecutiveStack(): csp: %#p\n", (void *)csp);
ptraddr_t cspAddr = (ptraddr_t)csp;
ptraddr_t cspEndAddr =
__builtin_cheri_base_get(csp) + __builtin_cheri_length_get(csp);
// Ensure this has the correct trusted frame size.
return cspAddr > (cspEndAddr - CI.kTrustedFrameSize);
}

template <typename A, typename R>
bool DwarfInstructions<A, R>::isTrampoline(uintcap_t ecsp, A &addressSpace,
CompartmentInfo &CI,
uintcap_t returnAddress) {
// TODO(cheri): Use a cfp-based approach rather than the cookie.
ptraddr_t expectedReturnAddress =
addressSpace.get64(ecsp + CI.kReturnAddressOffset) & (~0b11ULL);
addressSpace.get64(ecsp + CI.kReturnAddressOffset);
CHERI_DBG("isTrampoline(): expectedReturnAddress: 0x%lx\n",
expectedReturnAddress);
return expectedReturnAddress == returnAddress - 1;
return expectedReturnAddress == returnAddress;
}
#else // _LIBUNWIND_TARGET_AARCH64
template <typename A, typename R>
Expand All @@ -376,12 +363,6 @@ uintptr_t DwarfInstructions<A, R>::restoreRegistersFromSandbox(
return (uintptr_t)0;
}
template <typename A, typename R>
bool DwarfInstructions<A, R>::isEndOfExecutiveStack(uintcap_t csp,
CompartmentInfo &CI) {
assert(0 && "not implemented on this architecture");
return false;
}
template <typename A, typename R>
bool DwarfInstructions<A, R>::isTrampoline(uintcap_t ecsp, A &addressSpace,
CompartmentInfo &CI,
uintcap_t returnAddress) {
Expand Down Expand Up @@ -575,23 +556,13 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pc_t pc,
// compartment boundary. We need to restore registers from the executive
// stack and ask rtld for it.
if (addressSpace.isValidSealer(sealer)) {
// Iteratively unwind all the executive mode return addresses. This is
// necessary to support tail calls to trampolines.
uintcap_t csp = registers.getUnsealedECSP(sealer);
CompartmentInfo &CI = CompartmentInfo::sThisCompartmentInfo;
for (;;) {
if (isEndOfExecutiveStack(csp, CI)) {
return UNW_ESTOPUNWIND;
}
if (isTrampoline(csp, addressSpace, CI, returnAddress)) {
CHERI_DBG("%#p: detected a trampoline, unwinding from sandbox\n",
(void *)returnAddress);
returnAddress = restoreRegistersFromSandbox(
csp, addressSpace, newRegisters, CI, sealer);
csp = newRegisters.getUnsealedECSP(sealer);
} else {
break;
}
if (csp != 0 && isTrampoline(csp, addressSpace, CI, returnAddress)) {
CHERI_DBG("%#p: detected a trampoline, unwinding from sandbox\n",
(void *)returnAddress);
returnAddress = restoreRegistersFromSandbox(
csp, addressSpace, newRegisters, CI, sealer);
}
}
#endif
Expand Down

0 comments on commit bfc94ec

Please sign in to comment.