Documentation ¶
Overview ¶
Package sysmsg provides a stub signal handler and a communication protocol between stub threads and the Sentry.
Note that this package is allowlisted for use of sync/atomic.
+checkalignedignore
Index ¶
Constants ¶
const ( // PerThreadMemSize is the size of a per-thread memory region. PerThreadMemSize = 8 * hostarch.PageSize // GuardSize is the size of an unmapped region which is placed right // before the signal stack. GuardSize = hostarch.PageSize PerThreadPrivateStackOffset = GuardSize PerThreadPrivateStackSize = 2 * hostarch.PageSize // PerThreadStackSharedSize is the size of a per-thread stack region. // the thread stack. MsgOffsetFromSharedStack = PerThreadMemSize - hostarch.PageSize - PerThreadSharedStackOffset // SpinningQueueMemSize is the size of a spinning queue memory region. SpinningQueueMemSize = hostarch.PageSize )
LINT.IfChange Per-thread stack layout:
*------------* | guard page | |------------| | | | sysstack | | | *------------* | guard page | |------------| | | | ^ | | / \ | | | | | altstack | |------------| | sysmsg | *------------*
const ( // MaxFPStateLen is the largest possible FPState that we will save. // Note: This value was chosen to be able to fit ThreadContext into one page. MaxFPStateLen uint32 = 3584 // AllocatedSizeofThreadContextStruct defines how much memory to allocate for // one instance of ThreadContext. // We over allocate the memory for it because: // - The next instances needs to align to 64 bytes for purposes of xsave. // - It's nice to align it to the page boundary. AllocatedSizeofThreadContextStruct uintptr = 4096 )
Variables ¶
var SighandlerBlob []byte
SighandlerBlob contains the compiled code of the sysmsg signal handler.
Functions ¶
func MsgToStackAddr ¶
MsgToStackAddr returns a start address of a stack.
func StackAddrToMsg ¶
StackAddrToMsg returns an address of a sysmsg structure.
func StackAddrToSyshandlerStack ¶
StackAddrToSyshandlerStack returns an address of a syshandler stack.
Types ¶
type ArchState ¶
type ArchState struct {
// contains filtered or unexported fields
}
ArchState defines variables specific to the architecture being used.
type ContextState ¶
type ContextState uint32
ContextState defines the reason the context has exited back to the sentry, or ContextStateNone if running/ready-to-run.
const ( // ContextStateNone means that is either running in the user task or is ready // to run in the user task. ContextStateNone ContextState = iota // ContextStateSyscall means that a syscall event is triggered from the // sighandler. ContextStateSyscall // ContextStateFault means that there is a fault event that needs to be // handled. ContextStateFault // ContextStateSyscallTrap means that a syscall event is triggered from // a function call (syshandler). ContextStateSyscallTrap // ContextStateSyscallCanBePatched means that the syscall can be replaced // with a function call. ContextStateSyscallCanBePatched // ContextStateInvalid is an invalid state that the sentry should never see. ContextStateInvalid )
Context State types.
func (*ContextState) Get ¶
func (s *ContextState) Get() ContextState
Get returns the current state value.
func (*ContextState) Set ¶
func (s *ContextState) Set(state ContextState)
Set atomicaly sets the state value.
type Msg ¶
type Msg struct { // The next batch of fields is used to call the syshandler stub // function. A system call can be replaced with a function call. When // a function call is executed, it can't change the current process // stack, so it needs to save stack and instruction registers, switch // on its syshandler stack and call the jmp instruction to the syshandler // address. // // Self is a pointer to itself in a process address space. Self uint64 // RetAddr is a return address from the syshandler function. RetAddr uint64 // Syshandler is an address of the syshandler function. Syshandler uint64 // SyshandlerStack is an address of the thread syshandler stack. SyshandlerStack uint64 // AppStack is a value of the stack register before calling the syshandler // function. AppStack uint64 // State indicates to the sentry what the sysmsg thread is doing at a given // moment. State ThreadState // Context is a pointer to the ThreadContext struct that the current sysmsg // thread is processing. Context uint64 // FaultJump is the size of a faulted instruction. FaultJump int32 // Err is the error value with which the {sig|sys}handler crashes the stub // thread (see sysmsg.h:__panic). Err int32 // ErrAdditional is an error value that gives additional information // about the panic. ErrAdditional int32 // Line is the code line on which the {sig|sys}handler crashed the stub thread // (see sysmsg.h:panic). Line int32 // Debug is a variable to use to get visibility into the stub from the sentry. Debug uint64 // ThreadID is the ID of the sysmsg thread. ThreadID uint32 // contains filtered or unexported fields }
Msg contains the current state of the sysmsg thread.
func (*Msg) ConvertSysmsgErr ¶
func (m *Msg) ConvertSysmsgErr() *platform.ContextError
ConvertSysmsgErr converts m.Err to platform.ContextError.
type StubError ¶
type StubError int32
StubError are values that represent known stub-thread failure modes. Since these errors originate from the stub threads, look at sysmsg.h:stub_error.
const ( // StubErrorBadSysmsg indicates sysmsg->self did not match sysmsg. StubErrorBadSysmsg StubError = 0x0bad0000 + iota // StubErrorBadThreadState indicates sysmsg->state was invalid. StubErrorBadThreadState // StubErrorBadSpinningQueueDecref indicates stubs removed more threads // from spinning queue than were put in. StubErrorBadSpinningQueueDecref // StubErrorArchPrctl indicates an error when calling arch_prctl. StubErrorArchPrctl // StubErrorFutex indicates an error when calling futex. StubErrorFutex // StubErrorBadContextID indicates a context received from the context // queue was of unexpected value. StubErrorBadContextID // StubErrorFpStateBadHeader indicates that the floating point state // header did not match the expected value. StubErrorFpStateBadHeader )
type ThreadContext ¶
type ThreadContext struct { // FPState is a region of memory where: // - syshandler saves FPU state to using xsave/fxsave // - sighandler copies FPU state to from ucontext->uc_mcontext.fpregs // Note that xsave requires this region of memory to be 64 byte aligned; // therefore allocations of ThreadContext must be too. FPState [MaxFPStateLen]byte // FPStateChanged is set to true when the stub thread needs to restore FPState // because the sentry changed it. FPStateChanged uint64 // Regs is the context's GP register set. The {sig|sys}handler will save and // restore the user app's registers here. Regs linux.PtraceRegs // SignalInfo is the siginfo struct. SignalInfo linux.SignalInfo // Signo is the signal that the stub is requesting the sentry to handle. Signo int64 // State indicates the reason why the context has exited back to the sentry. State ContextState // Interrupt is set to indicate that this context has been interrupted. Interrupt uint32 // ThreadID is the ID of the sysmsg thread that's currently working on the // context. ThreadID uint32 // LastThreadID is the ID of the previous sysmsg thread that ran the context // (not the one currently working on it). This field is used by sysmsg threads // to detect whether fpstate may have changed since the last time they ran a // context. LastThreadID uint32 // SentryFastPath is used to indicate to the stub thread that the sentry // goroutine used for this thread context is busy-polling for a response // instead of using FUTEX_WAIT. SentryFastPath uint32 // AckedTime is used by sysmsg threads to signal to the sentry that this context // has been picked up from the context queue and is actively being worked on. // The stub thread puts down the timestamp at which it has started processing // this context. AckedTime uint64 // StateChangedTime is the time when the ThreadContext.State changed, as // recorded by the stub thread when it gave it back to the sentry // (the sentry does not populate this field except to reset it). StateChangedTime uint64 // TLS is a pointer to a thread local storage. // It is is only populated on ARM64. TLS uint64 // Debug is a variable to use to get visibility into the stub from the sentry. Debug uint64 // SigError is an error code that clarifies the nature of the signal. SigError uint64 }
ThreadContext contains the current context of the sysmsg thread. The struct facilitates switching contexts by allowing the sentry to switch pointers to this struct as it needs to.
func (*ThreadContext) Init ¶
func (c *ThreadContext) Init(initialThreadID uint32)
Init initializes the ThreadContext instance.
func (*ThreadContext) SleepOnState ¶
func (c *ThreadContext) SleepOnState(curState ContextState, timeout *unix.Timespec) syscall.Errno
SleepOnState makes the caller sleep on the ThreadContext.State futex.
func (*ThreadContext) String ¶
func (c *ThreadContext) String() string
type ThreadState ¶
type ThreadState uint32
ThreadState is used to store a state of the sysmsg thread.
const ( // ThreadStateNone means that the thread is executing the user workload. ThreadStateNone ThreadState = iota // ThreadStateDone means that last event has been handled and the stub thread // can be resumed. ThreadStateDone // ThreadStatePrep means that syshandler started filling the sysmsg struct. ThreadStatePrep // ThreadStateAsleep means that this thread fell asleep because there was not // enough contexts to process in the context queue. ThreadStateAsleep // ThreadStateInitializing is only set once at sysmsg thread creation time. It // is used to tell the signal handler that the thread does not yet have a // context. ThreadStateInitializing )
func (*ThreadState) CompareAndSwap ¶
func (s *ThreadState) CompareAndSwap(old, state ThreadState) bool
CompareAndSwap atomicaly compares and swaps the state value.
func (*ThreadState) Get ¶
func (s *ThreadState) Get() ThreadState
Get returns the current state value.
func (*ThreadState) Set ¶
func (s *ThreadState) Set(state ThreadState)
Set atomicaly sets the state value.