From f9c7e51064c193ae347f4ff85c1668c3453c63bb Mon Sep 17 00:00:00 2001 From: Andrei Vagin Date: Fri, 11 Oct 2024 10:18:25 -0700 Subject: [PATCH] systrap/arm64: add the `end` header after FPSIMD state in signal frame gVisor doesn't support other than FPSIMD extension, so we have to be sure that only FPSIMD states are restored from signal frames. Stub processes are forked from the sentry and so they can have other extensions such as SVE which shares FPSR and FPCR registers with FPSIMD. Fixes #10900 PiperOrigin-RevId: 684878144 --- .../platform/systrap/sysmsg/sighandler_arm64.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/pkg/sentry/platform/systrap/sysmsg/sighandler_arm64.c b/pkg/sentry/platform/systrap/sysmsg/sighandler_arm64.c index 2470a755e..1173b8a94 100644 --- a/pkg/sentry/platform/systrap/sysmsg/sighandler_arm64.c +++ b/pkg/sentry/platform/systrap/sysmsg/sighandler_arm64.c @@ -122,16 +122,21 @@ void __export_sighandler(int signo, siginfo_t *siginfo, void *_ucontext) { // point context. // // See: arch/arm64/include/uapi/asm/sigcontext.h - const uint64_t kSigframeMagicHeaderLen = sizeof(struct _aarch64_ctx); + const uint64_t kFpsimdContextSize = + sizeof(struct fpsimd_context) - sizeof(struct _aarch64_ctx); + struct fpsimd_context *fpctx = + (struct fpsimd_context *)&ucontext->uc_mcontext.__reserved; + uint8_t *fpStatePointer = (uint8_t *)&fpctx->fpsr; + // Verify the header. - if (((uint32_t *)&ucontext->uc_mcontext.__reserved)[0] != FPSIMD_MAGIC) { + if (fpctx->head.magic != FPSIMD_MAGIC || + __export_arch_state.fp_len < kFpsimdContextSize || + fpctx->head.size != sizeof(struct fpsimd_context)) { panic(STUB_ERROR_FPSTATE_BAD_HEADER, ((uint32_t *)&ucontext->uc_mcontext.__reserved)[0]); } - uint8_t *fpStatePointer = - (uint8_t *)&ucontext->uc_mcontext.__reserved + kSigframeMagicHeaderLen; - memcpy(ctx->fpstate, fpStatePointer, __export_arch_state.fp_len); + memcpy(ctx->fpstate, fpStatePointer, kFpsimdContextSize); ctx->tls = get_tls(); ctx->siginfo = *siginfo; switch (signo) { @@ -192,6 +197,8 @@ void restore_state(struct sysmsg *sysmsg, struct thread_context *ctx, if (atomic_load(&ctx->fpstate_changed)) { memcpy(fpStatePointer, ctx->fpstate, __export_arch_state.fp_len); + fpctx[1].head.size = 0; + fpctx[1].head.magic = 0; } ptregs_to_gregs(ucontext, &ctx->ptregs); set_tls(ctx->tls);