diff --git a/pkg/sentry/platform/systrap/subprocess.go b/pkg/sentry/platform/systrap/subprocess.go index c97816e36..9d2e6fcb3 100644 --- a/pkg/sentry/platform/systrap/subprocess.go +++ b/pkg/sentry/platform/systrap/subprocess.go @@ -675,10 +675,7 @@ func (s *subprocess) switchToApp(c *context, ac *arch.Context64) (isSyscall bool if ctx.State == sysmsg.ContextStateSyscallCanBePatched { ctx.State = sysmsg.ContextStateSyscall - // Syshandler not implemented with context decoupling yet. - if !contextDecouplingExp { - shouldPatchSyscall = true - } + shouldPatchSyscall = true } if ctx.State == sysmsg.ContextStateSyscall || ctx.State == sysmsg.ContextStateSyscallTrap { @@ -750,10 +747,6 @@ func (s *subprocess) Unmap(addr hostarch.Addr, length uint64) { } func (s *subprocess) PullFullState(c *context, ac *arch.Context64) error { - if !contextDecouplingExp { - return s.PullFullArchState(c, ac) - } - if s != c.subprocess { panic("Attempted to PullFullState for context that is not used in subprocess") } @@ -857,10 +850,10 @@ func (s *subprocess) getSysmsgThread(tregs *arch.Registers, c *context, ac *arch sysThread.setMsg(sysmsg.StackAddrToMsg(sentryStackAddr)) sysThread.msg.Init() sysThread.msg.Self = uint64(sysmsgStackAddr + sysmsg.MsgOffsetFromSharedStack) - sysThread.msg.Syshandler = uint64(stubSysmsgStart + uintptr(sysmsg.Sighandler_blob_offset____export_syshandler)) sysThread.msg.SyshandlerStack = uint64(sysmsg.StackAddrToSyshandlerStack(sysThread.sysmsgPerThreadMemAddr())) sysThread.msg.ContextRegion = uint64(stubContextRegion) sysThread.msg.ContextID = c.cid + sysThread.msg.Syshandler = uint64(stubSysmsgStart + uintptr(sysmsg.Sighandler_blob_offset____export_syshandler)) sysThread.msg.State.Set(sysmsg.ThreadStateDone) diff --git a/pkg/sentry/platform/systrap/subprocess_amd64.go b/pkg/sentry/platform/systrap/subprocess_amd64.go index 7071d11aa..14b8fb076 100644 --- a/pkg/sentry/platform/systrap/subprocess_amd64.go +++ b/pkg/sentry/platform/systrap/subprocess_amd64.go @@ -211,74 +211,6 @@ func appendArchSeccompRules(rules []seccomp.RuleSet) []seccomp.RuleSet { }...) } -func (s *subprocess) PullFullArchState(c *context, ac *arch.Context64) error { - // Reset necessary registers. - regs := &ac.StateData().Regs - - sysThread, err := s.getSysmsgThread(regs, c, ac) - if err != nil { - return err - } - msg := sysThread.msg - ctx := s.getThreadContextFromID(c.cid) - - // In case of EventTypeSyscallTrap, we have only syscall argument - // registers and we need to trigger a signal in the stub process to get - // a full set of registers and an FPU state. - // - // In other cases, we have the full set of registers and need only copy - // the FPU state from a signal frame. - if ctx.State != sysmsg.ContextStateSyscallTrap { - s.saveFPState(msg, ctx, sysThread.fpuStateToMsgOffset, c, ac) - return nil - } - - // In case of EventTypeSyscallTrap, the Sentry knows only the syscall - // number and syscall arguments and the target thread is stopped in the - // syshandler stub function. We need to ask syshandler to trigger a - // real syscall to get the full state. - ctx.Regs = regs.PtraceRegs - - sysThread.waitEvent(sysmsg.ThreadStateSigact) - - if msg.Err != 0 { - panic(fmt.Sprintf("stub thread failed: err %d line %d: %s", msg.Err, msg.Line, msg)) - } - - if ctx.State != sysmsg.ContextStateSyscall { - panic(fmt.Sprintf("unknown context state: state %v: %s", ctx.State, msg)) - } - - sysThread.fpuStateToMsgOffset, err = msg.FPUStateOffset() - if err != nil { - return err - } - - // When we are triggering the real syscall instruction, we don't - // restore all syscall arguments and even the syscall number. - ctx.Regs.Rax = regs.Rax - ctx.Regs.Orig_rax = regs.Orig_rax - ctx.Regs.Rdi = regs.Rdi - ctx.Regs.Rsi = regs.Rsi - ctx.Regs.Rdx = regs.Rdx - ctx.Regs.R10 = regs.R10 - ctx.Regs.R8 = regs.R8 - ctx.Regs.R9 = regs.R9 - regs.PtraceRegs = ctx.Regs - - // The thread has restored all registers that could be changed in - // the syshandler stub function, but it is still in this function. We - // know the return address and let's set it so to be not affected if - // the stub code will be changed after save/restore. - regs.Rip = msg.RetAddr - - s.saveFPState(msg, ctx, sysThread.fpuStateToMsgOffset, c, ac) - - c.signalInfo = ctx.SignalInfo - - return nil -} - func restoreArchSpecificState(regs *arch.Registers, t *thread, sysThread *sysmsgThread, msg *sysmsg.Msg, _ *arch.Context64) { regs.Gs_base = msg.Self diff --git a/pkg/sentry/platform/systrap/subprocess_arm64.go b/pkg/sentry/platform/systrap/subprocess_arm64.go index 8568732d5..ae6f0bf9f 100644 --- a/pkg/sentry/platform/systrap/subprocess_arm64.go +++ b/pkg/sentry/platform/systrap/subprocess_arm64.go @@ -187,19 +187,6 @@ func (s *subprocess) arm64SyscallWorkaround(t *thread, regs *arch.Registers) { } } -func (s *subprocess) PullFullArchState(c *context, ac *arch.Context64) error { - // We do not support syscall trap in ARM64 so just get the fp state from the - // signal frame and we are done. - regs := &ac.StateData().Regs - sysThread, err := s.getSysmsgThread(regs, c, ac) - if err != nil { - return err - } - ctx := s.getThreadContextFromID(c.cid) - s.saveFPState(sysThread.msg, ctx, sysThread.fpuStateToMsgOffset, c, ac) - return nil -} - func restoreArchSpecificState(regs *arch.Registers, t *thread, _ *sysmsgThread, msg *sysmsg.Msg, ac *arch.Context64) { msg.TLS = uint64(ac.TLS()) } diff --git a/pkg/sentry/platform/systrap/sysmsg/sighandler_amd64.c b/pkg/sentry/platform/systrap/sysmsg/sighandler_amd64.c index 87b673049..2b7c0a2ac 100644 --- a/pkg/sentry/platform/systrap/sysmsg/sighandler_amd64.c +++ b/pkg/sentry/platform/systrap/sysmsg/sighandler_amd64.c @@ -177,8 +177,7 @@ void __export_sighandler(int signo, siginfo_t *siginfo, void *_ucontext) { // because sysmsg can't be changed. int32_t thread_state; thread_state = __atomic_load_n(&sysmsg->state, __ATOMIC_ACQUIRE); - if ((thread_state != THREAD_STATE_NONE) || - (ucontext->uc_mcontext.gregs[REG_RSP] > (unsigned long)sp)) { + if (thread_state != THREAD_STATE_NONE) { __atomic_store_n(&sysmsg->interrupt, 1, __ATOMIC_RELEASE); return; } @@ -189,6 +188,13 @@ void __export_sighandler(int signo, siginfo_t *siginfo, void *_ucontext) { __atomic_store_n(&sysmsg->interrupt, 0, __ATOMIC_RELAXED); // Skip the fault instruction. ucontext->uc_mcontext.gregs[REG_RIP] = sysmsg->ret_addr; + // If we're skipping the fault instruction and going straight to the user + // RIP we must also restore RSP and RFLAGS which are the last registers + // restored. We can take these values from ctx->ptregs because the + // syshandler saved them there and hasn't overwritten them before + // retriggering the interrupt. + ucontext->uc_mcontext.gregs[REG_RSP] = ctx->ptregs.rsp; + ucontext->uc_mcontext.gregs[REG_EFL] = ctx->ptregs.eflags; } // Handle faults in syshandler. @@ -220,12 +226,7 @@ void __export_sighandler(int signo, siginfo_t *siginfo, void *_ucontext) { // If a syscall instruction set is "mov sysno, %eax, syscall", it can be // replaced on a function call which works much faster. // Look at pkg/sentry/usertrap for more details. - // - // Exclude all syscalls which requires a full thread state to be handled. - if (siginfo->si_arch == AUDIT_ARCH_X86_64 && si_sysno != __NR_execveat && - si_sysno != __NR_execve && si_sysno != __NR_fork && - si_sysno != __NR_clone && si_sysno != __NR_vfork && - si_sysno != __NR_rt_sigreturn && si_sysno != __NR_arch_prctl) { + if (siginfo->si_arch == AUDIT_ARCH_X86_64) { uint8_t *rip = (uint8_t *)ctx->ptregs.rip; // FIXME(b/144063246): Even if all five bytes before the syscall // instruction match the "mov sysno, %eax" instruction, they can be a @@ -314,49 +315,32 @@ void __export_sighandler(int signo, siginfo_t *siginfo, void *_ucontext) { __atomic_store_n(&sysmsg->state, THREAD_STATE_NONE, __ATOMIC_RELEASE); } -// Function arguments: %rdi,%rsi, %rdx, %rcx, %r8 and %r9. -// http://refspecs.linuxfoundation.org/elf/x86_64-abi-0.99.pdf -long __syshandler(long a1, long a2, long a3, long __unused, long a5, long a6) { - long sysno, a4, rip; +void __syshandler() { struct sysmsg *sysmsg; - asm volatile( - "movq %%rax, %0\n" - "movq %%r10, %1\n" - : "=m"(sysno), "=m"(a4) - : - :); asm volatile("movq %%gs:0, %0\n" : "=r"(sysmsg) : :); - struct thread_context *ctx = thread_context_addr(sysmsg); - // SYSMSG_STATE_PREP is set to postpone interrupts. Look at // __export_sighandler for more details. - int thread_state = __atomic_load_n(&sysmsg->state, __ATOMIC_ACQUIRE); - if (thread_state != THREAD_STATE_PREP) panic(thread_state); - ctx->signo = SIGSYS; - ctx->ptregs.rax = sysno; - ctx->ptregs.rdi = a1; - ctx->ptregs.rsi = a2; - ctx->ptregs.rdx = a3; - ctx->ptregs.r10 = a4; - ctx->ptregs.r8 = a5; - ctx->ptregs.r9 = a6; - ctx->ptregs.rsp = sysmsg->app_stack; - ctx->ptregs.rip = sysmsg->ret_addr; + int state = __atomic_load_n(&sysmsg->state, __ATOMIC_ACQUIRE); + if (state != THREAD_STATE_PREP) panic(state); + + struct thread_context *ctx = thread_context_addr(sysmsg); + ctx->state = CONTEXT_STATE_SYSCALL_TRAP; - ctx->ptregs.orig_rax = ctx->ptregs.rax; - ctx->ptregs.rax = (unsigned long)-ENOSYS; + ctx->signo = SIGSYS; ctx->siginfo.si_addr = 0; - ctx->siginfo.si_syscall = sysno; + ctx->siginfo.si_syscall = ctx->ptregs.rax; + ctx->ptregs.rax = (unsigned long)-ENOSYS; __atomic_store_n(&sysmsg->interrupt, 0, __ATOMIC_RELAXED); - thread_state = wait_state(sysmsg, THREAD_STATE_EVENT); - long sysret = ctx->ptregs.rax; - if (thread_state == THREAD_STATE_SIGACT) { - return -1; - } + get_fsbase(&ctx->ptregs); + long fs_base = ctx->ptregs.fs_base; - __atomic_store_n(&sysmsg->state, THREAD_STATE_NONE, __ATOMIC_RELEASE); - return sysret; + state = wait_state(sysmsg, THREAD_STATE_EVENT); + + // Restore state + if (fs_base != ctx->ptregs.fs_base) { + set_fsbase(&ctx->ptregs); + } } void verify_offsets_amd64() { diff --git a/pkg/sentry/platform/systrap/sysmsg/syshandler_amd64.S b/pkg/sentry/platform/systrap/sysmsg/syshandler_amd64.S index 0ac39a112..e66b5f908 100644 --- a/pkg/sentry/platform/systrap/sysmsg/syshandler_amd64.S +++ b/pkg/sentry/platform/systrap/sysmsg/syshandler_amd64.S @@ -13,66 +13,208 @@ // limitations under the License. #include "sysmsg_offsets.h" +#include "sysmsg_offsets_amd64.h" +// Helper macros: +//////////////////////////////////////// + +// load_thread_context loads the address of the thread context slot for the current +// context. +// Clobbers %rflags; loads address into %rcx. +.macro load_thread_context_addr + movl %gs:offsetof_sysmsg_context_id, %ecx + shl $THREAD_CONTEXT_STRUCT_BITSHIFT, %rcx + add %gs:offsetof_sysmsg_context_region, %rcx +.endm + +// prepare_enter_syshandler does the following: +// - saves all registers that are restorable onto the thread_context struct. +// - loads the address of the thread_context struct into %rcx. +.macro prepare_enter_syshandler + // Syshandler clobbers rflags (load_thread_context_addr does so for example). + // Therefore save it as the first thing we do. + pushfq + // load_thread_context_addr overwrites %rcx. + push %rcx + + load_thread_context_addr + + // Registers listed in order as written in ptregs: + movq %r15, offsetof_thread_context_ptregs_r15(%rcx) + movq %r14, offsetof_thread_context_ptregs_r14(%rcx) + movq %r13, offsetof_thread_context_ptregs_r13(%rcx) + movq %r12, offsetof_thread_context_ptregs_r12(%rcx) + movq %rbp, offsetof_thread_context_ptregs_rbp(%rcx) + movq %rbx, offsetof_thread_context_ptregs_rbx(%rcx) + movq %r11, offsetof_thread_context_ptregs_r11(%rcx) + movq %r10, offsetof_thread_context_ptregs_r10(%rcx) + movq %r9, offsetof_thread_context_ptregs_r9(%rcx) + movq %r8, offsetof_thread_context_ptregs_r8(%rcx) + movq %rax, offsetof_thread_context_ptregs_rax(%rcx) + pop %r15 + movq %r15, offsetof_thread_context_ptregs_rcx(%rcx) + movq %rdx, offsetof_thread_context_ptregs_rdx(%rcx) + movq %rsi, offsetof_thread_context_ptregs_rsi(%rcx) + movq %rdi, offsetof_thread_context_ptregs_rdi(%rcx) + movq %rax, offsetof_thread_context_ptregs_orig_rax(%rcx) + + movw %cs, offsetof_thread_context_ptregs_cs(%rcx) + movw %ss, offsetof_thread_context_ptregs_ss(%rcx) + // Don't bother save/restoring ds/es on amd64 + // movw %ds, offsetof_thread_context_ptregs_ds(%rcx) + // movw %es, offsetof_thread_context_ptregs_es(%rcx) + movw %fs, offsetof_thread_context_ptregs_fs(%rcx) + movw %gs, offsetof_thread_context_ptregs_gs(%rcx) + + pop %rax + movq %rax, offsetof_thread_context_ptregs_eflags(%rcx) + + movq %gs:offsetof_sysmsg_app_stack, %r8 + movq %r8, offsetof_thread_context_ptregs_rsp(%rcx) + movq %gs:offsetof_sysmsg_ret_addr, %r9 + movq %r9, offsetof_thread_context_ptregs_rip(%rcx) +.endm + +// prepare_exit_syshandler assumes that: +// - the memory address of the thread_context is loaded in %rcx. +// prepare_exit_syshandler does the following: +// - sets sysmsg->ret_addr +// - restores all registers that were saved inside the thread_context struct except for +// %rsp and rflags. +// - %rcx will be restored as well, and will no longer contain the memory address to the +// thread context. +// - puts user %rsp and rflags onto the syshandler stack (in that order). rflags cannot +// be restored at this point because syshandler will clobber it before it exits. +.macro prepare_exit_syshandler + movq offsetof_thread_context_ptregs_rsp(%rcx), %rax + push %rax + movq offsetof_thread_context_ptregs_eflags(%rcx), %rbx + push %rbx + + // set sysmsg->ret_addr + movq offsetof_thread_context_ptregs_rip(%rcx), %r9 + movq %r9, %gs:offsetof_sysmsg_ret_addr + + // Restore segments. Because restoring segments is slow, restore them only if necessary. + movw %fs, %dx + cmpw %dx, offsetof_thread_context_ptregs_fs(%rcx) + je restored_fs + movw offsetof_thread_context_ptregs_fs(%rcx), %fs +restored_fs: + movw %gs, %si + cmpw %si, offsetof_thread_context_ptregs_gs(%rcx) + je restored_gs + movw offsetof_thread_context_ptregs_gs(%rcx), %gs +restored_gs: + // Restore other GP registers + movq offsetof_thread_context_ptregs_r15(%rcx), %r15 + movq offsetof_thread_context_ptregs_r14(%rcx), %r14 + movq offsetof_thread_context_ptregs_r13(%rcx), %r13 + movq offsetof_thread_context_ptregs_r12(%rcx), %r12 + movq offsetof_thread_context_ptregs_rbp(%rcx), %rbp + movq offsetof_thread_context_ptregs_rbx(%rcx), %rbx + movq offsetof_thread_context_ptregs_r11(%rcx), %r11 + movq offsetof_thread_context_ptregs_r10(%rcx), %r10 + movq offsetof_thread_context_ptregs_r9(%rcx), %r9 + movq offsetof_thread_context_ptregs_r8(%rcx), %r8 + movq offsetof_thread_context_ptregs_rax(%rcx), %rax + // %rcx restored last + movq offsetof_thread_context_ptregs_rdx(%rcx), %rdx + movq offsetof_thread_context_ptregs_rsi(%rcx), %rsi + movq offsetof_thread_context_ptregs_rdi(%rcx), %rdi + + movq offsetof_thread_context_ptregs_rcx(%rcx), %rcx +.endm + +// save_fpstate saves the current fpstate onto thread_context.fpstate. +// It assumes that: +// - the memory address of the thread_context is loaded in %rcx. +.macro save_fpstate + lea offsetof_thread_context_fpstate(%rcx), %rdi + movl $0xffffffff, %eax + movl $0xffffffff, %edx + movl __export_arch_state+offsetof_arch_state_xsave_mode(%rip), %esi + // TODO(b/268366549): Fix use of xsavec/xsaveopt. + // cmpl $XSAVE_MODE_XSAVEC, %esi + // jl use_xsaveopt + // xsavec (%rdi) + // jmp fpu_saved + // use_xsaveopt: + // cmpl $XSAVE_MODE_XSAVEOPT, %esi + // jl use_xsave + // xsaveopt (%rdi) + // jmp fpu_saved + // use_xsave: + cmpl $XSAVE_MODE_XSAVE, %esi + jl use_fxsave + xsave (%rdi) + jmp fpu_saved +use_fxsave: + fxsave (%rdi) +fpu_saved: +.endm + +// restore_fpstate restores the fpstate previously saved onto thread_context.fpstate. +// It assumes that: +// - the memory address of the thread_context is loaded in %rcx. +.macro restore_fpstate + // We only need to restore fpstate if we were signalled that it changed (syshandler + // does not modify fpstate). + cmpl $0, offsetof_thread_context_fpstate_changed(%rcx) + je fpu_restored + + lea offsetof_thread_context_fpstate(%rcx), %rdi + mov __export_arch_state+offsetof_arch_state_xsave_mode(%rip), %eax + cmpl $XSAVE_MODE_FXSAVE, %eax + jz use_fxrstor +use_xrstor: + movl $0xffffffff, %eax + movl $0xffffffff, %edx + xrstor (%rdi) + jmp fpu_restored +use_fxrstor: + fxrstor (%rdi) +fpu_restored: +.endm + +// Syshandler: +//////////////////////////////////////// .globl __export_syshandler; .type __export_syshandler, @function; .align 4, 0x00; __export_syshandler: // The start of this function is in a usertrap trampoline: - // mov %rsp,%gs:0x20 - // mov %gs:0x18,%rs + // mov sysmsg.ThreadStatePrep, %gs:offset(msg.State) + // mov %rsp,%gs:0x20 // msg.AppStack + // mov %gs:0x18,%rsp // msg.SyshandlerStack // movabs $ret_addr, %rax - // mov %rax, %fs:0x8 - // mov sysno, %eax - // jmpq *%gs,0x10 + // mov %rax,%gs:0x8 // msg.RetAddr + // mov sysno,%eax + // jmpq *%gs:0x10 // msg.Syshandler + prepare_enter_syshandler + save_fpstate - // Save registers which are not preserved across function calls. - // http://refspecs.linuxfoundation.org/elf/x86_64-abi-0.99.pdf - push %rbp - push %r11 - push %r10 - push %r9 - push %r8 - push %rdi - push %rsi - push %rdx - push %rcx - - // We have to avoid races with sighandler, so if sysmsg isn't equal to - // SYSMSG_STATE_NONE, we can't fault on a user stack. - // - // We can fault on a user stack, what a page isn't mapped yet or when a - // process is dieing and a process address spaces has been cleaned up (see - // subprocess.Release). callq __syshandler - // Restore registers and return back to a guest code. - pop %rcx - pop %rdx - pop %rsi - pop %rdi - pop %r8 - pop %r9 - pop %r10 - pop %r11 - pop %rbp + // thread_context may have changed, therefore we reload it into %rcx anew. + load_thread_context_addr + restore_fpstate - movq %gs:offsetof_sysmsg_app_stack,%rsp + prepare_exit_syshandler - cmpl $kTHREAD_STATE_SIGACT, %gs:offsetof_sysmsg_state // msg->state - jne skipsyscall - mov $0xffff, %eax // any syscall which isn't allowed by seccomp. - // nop is here to avoid matching the `mov sysno, %eax; syscall` pattern that - // we are substituting with function calls. - nop - syscall - jmp skipint -skipsyscall: + // Indicate syshandler is done. + movl $kTHREAD_STATE_NONE, %gs:offsetof_sysmsg_state + + // Check if syshandler received an interrupt while executing. + // If it did, retrigger the interrupt. See __export_sighandler for details. cmpl $0, %gs:offsetof_sysmsg_interrupt // msg->interrupt je skipint movl $kTHREAD_STATE_INTERRUPT, %gs:offsetof_sysmsg_state .byte FAULT_OPCODE // Re-trigger the interrupt. skipint: + // Now syshandler is exiting for good; restore user rflags and %rsp. + popfq + movq 0(%rsp), %rsp jmp *%gs:offsetof_sysmsg_ret_addr // msg->ret_addr .size __export_syshandler, . - __export_syshandler diff --git a/pkg/sentry/platform/systrap/sysmsg/sysmsg.go b/pkg/sentry/platform/systrap/sysmsg/sysmsg.go index 2a81974d4..0bab82026 100644 --- a/pkg/sentry/platform/systrap/sysmsg/sysmsg.go +++ b/pkg/sentry/platform/systrap/sysmsg/sysmsg.go @@ -108,10 +108,6 @@ const ( ThreadStateEvent // ThreadStatePrep means that syshandler started filling the sysmsg struct. ThreadStatePrep - // ThreadStateSigact means that the sentry requests the full state of the stub - // thread. - // TODO(b/268366549): Remove this when syshandler saves full state to context. - ThreadStateSigact // ThreadStateInterrupt is a Sysmsg state that indicates to the sighandler // that there is a postponed interrupt from the syshandler. // The sentry should never see this event. @@ -264,14 +260,6 @@ type ThreadContext struct { State ContextState // Interrupt is set to indicate that this context has been interrupted. Interrupt uint32 - // Decoupled is set to indicate that this context is not tied to the sysmsg - // thread used to to execute this context. This value is only changed from - // the sentry if contextDecouplingExp is on. - // It changes the behaviour of the sysmsg threads in the following ways: - // - sighandler will save fpstate to ThreadContext.FPState instead of on the - // sighandler stack. - // - syshandler will not save fpstate at all. - Decoupled uint32 // Debug is a variable to use to get visibility into the stub from the sentry. Debug uint64 } diff --git a/pkg/sentry/platform/systrap/sysmsg/sysmsg.h b/pkg/sentry/platform/systrap/sysmsg/sysmsg.h index 3b2a8a3b4..465f43ac1 100644 --- a/pkg/sentry/platform/systrap/sysmsg/sysmsg.h +++ b/pkg/sentry/platform/systrap/sysmsg/sysmsg.h @@ -42,7 +42,6 @@ enum { THREAD_STATE_DONE, THREAD_STATE_EVENT, THREAD_STATE_PREP, - THREAD_STATE_SIGACT, THREAD_STATE_INTERRUPT, }; @@ -95,7 +94,6 @@ struct thread_context { int64_t signo; uint32_t state; uint32_t interrupt; - uint32_t decoupled; uint64_t debug; }; diff --git a/pkg/sentry/platform/systrap/sysmsg/sysmsg_amd64.go b/pkg/sentry/platform/systrap/sysmsg/sysmsg_amd64.go index f4165b5e3..03a604953 100644 --- a/pkg/sentry/platform/systrap/sysmsg/sysmsg_amd64.go +++ b/pkg/sentry/platform/systrap/sysmsg/sysmsg_amd64.go @@ -51,11 +51,8 @@ func (s *ArchState) Init() { fpLenUint, _ := fs.ExtendedStateSize() s.fpLen = uint32(fpLenUint) - if fs.UseXsavec() { - s.xsaveMode = xsavec - } else if fs.UseXsaveopt() { - s.xsaveMode = xsaveopt - } else if fs.UseXsave() { + // TODO(b/268366549): Fix use of xsavec/xsaveopt. + if fs.UseXsave() { s.xsaveMode = xsave } else { s.xsaveMode = fxsave diff --git a/pkg/sentry/platform/systrap/sysmsg/sysmsg_lib.c b/pkg/sentry/platform/systrap/sysmsg/sysmsg_lib.c index 3622d69d4..358f3856f 100644 --- a/pkg/sentry/platform/systrap/sysmsg/sysmsg_lib.c +++ b/pkg/sentry/platform/systrap/sysmsg/sysmsg_lib.c @@ -90,13 +90,13 @@ int wait_state(struct sysmsg *sysmsg, uint32_t state) { } v = __atomic_load_n(&sysmsg->state, __ATOMIC_ACQUIRE); - if (v == THREAD_STATE_DONE || v == THREAD_STATE_SIGACT) goto out; + if (v == THREAD_STATE_DONE) goto out; handshake_timeout = __export_handshake_timeout; start = rdtsc(); while (1) { v = __atomic_load_n(&sysmsg->state, __ATOMIC_ACQUIRE); - if (v == THREAD_STATE_DONE || v == THREAD_STATE_SIGACT) goto out; + if (v == THREAD_STATE_DONE) goto out; // The Sentry can change stub_fast_path to zero if it finds out that the // user task has to sleep. @@ -154,7 +154,6 @@ void verify_offsets() { offsetof(struct thread_context, ptregs)); BUILD_BUG_ON(kTHREAD_STATE_NONE != THREAD_STATE_NONE); - BUILD_BUG_ON(kTHREAD_STATE_SIGACT != THREAD_STATE_SIGACT); BUILD_BUG_ON(kTHREAD_STATE_INTERRUPT != THREAD_STATE_INTERRUPT); BUILD_BUG_ON(sizeof(struct thread_context) > diff --git a/pkg/sentry/platform/systrap/sysmsg/sysmsg_offsets.h b/pkg/sentry/platform/systrap/sysmsg/sysmsg_offsets.h index b93cfd0b1..0c0ec5514 100644 --- a/pkg/sentry/platform/systrap/sysmsg/sysmsg_offsets.h +++ b/pkg/sentry/platform/systrap/sysmsg/sysmsg_offsets.h @@ -22,7 +22,10 @@ // LINT.IfChange #define MAX_FPSTATE_LEN 3648 +// Note: To be explicit, 2^12 = 4096; if ALLOCATED_SIZEOF_THREAD_CONTEXT_STRUCT +// is changed, make sure to change the code that relies on the bitshift. #define ALLOCATED_SIZEOF_THREAD_CONTEXT_STRUCT 4096 +#define THREAD_CONTEXT_STRUCT_BITSHIFT 12 // LINT.ThenChange(sysmsg.go) // LINT.IfChange @@ -44,8 +47,7 @@ #define offsetof_thread_context_ptregs 0x8 + MAX_FPSTATE_LEN #define kTHREAD_STATE_NONE 0 -#define kTHREAD_STATE_SIGACT 4 -#define kTHREAD_STATE_INTERRUPT 5 +#define kTHREAD_STATE_INTERRUPT 4 // LINT.ThenChange(sysmsg.h, sysmsg_lib.c)