mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Allow to return an error from PullFullState.
PiperOrigin-RevId: 504415294
This commit is contained in:
@@ -65,7 +65,12 @@ func (t *Task) Clone(args *linux.CloneArgs) (ThreadID, *SyscallControl, error) {
|
||||
|
||||
// Pull task registers and FPU state, a cloned task will inherit the
|
||||
// state of the current task.
|
||||
t.p.PullFullState(t.MemoryManager().AddressSpace(), t.Arch())
|
||||
if err := t.p.PullFullState(t.MemoryManager().AddressSpace(), t.Arch()); err != nil {
|
||||
t.Warningf("Unable to pull a full state: %v", err)
|
||||
t.forceSignal(linux.SIGILL, true /* unconditional */)
|
||||
t.SendSignal(SignalInfoPriv(linux.SIGILL))
|
||||
return 0, nil, linuxerr.EFAULT
|
||||
}
|
||||
|
||||
// "If CLONE_NEWUSER is specified along with other CLONE_NEW* flags in a
|
||||
// single clone(2) or unshare(2) call, the user namespace is guaranteed to
|
||||
|
||||
@@ -247,7 +247,10 @@ func (app *runApp) execute(t *Task) taskRunState {
|
||||
t.Arch().ClearSingleStep()
|
||||
}
|
||||
if t.hasTracer() {
|
||||
t.p.PullFullState(t.MemoryManager().AddressSpace(), t.Arch())
|
||||
if e := t.p.PullFullState(t.MemoryManager().AddressSpace(), t.Arch()); e != nil {
|
||||
t.Warningf("Unable to pull a full state: %v", e)
|
||||
err = e
|
||||
}
|
||||
}
|
||||
|
||||
switch err {
|
||||
|
||||
@@ -644,8 +644,9 @@ func (t *Task) SetSavedSignalMask(mask linux.SignalSet) {
|
||||
}
|
||||
|
||||
// SignalStack returns the task-private signal stack.
|
||||
//
|
||||
// By precondition, a full state has to be pulled.
|
||||
func (t *Task) SignalStack() linux.SignalStack {
|
||||
t.p.PullFullState(t.MemoryManager().AddressSpace(), t.Arch())
|
||||
alt := t.signalStack
|
||||
if t.onSignalStack(alt) {
|
||||
alt.Flags |= linux.SS_ONSTACK
|
||||
@@ -653,6 +654,34 @@ func (t *Task) SignalStack() linux.SignalStack {
|
||||
return alt
|
||||
}
|
||||
|
||||
// SigaltStack implements the sigaltstack syscall.
|
||||
func (t *Task) SigaltStack(setaddr hostarch.Addr, oldaddr hostarch.Addr) (*SyscallControl, error) {
|
||||
if err := t.p.PullFullState(t.MemoryManager().AddressSpace(), t.Arch()); err != nil {
|
||||
t.PrepareGroupExit(linux.WaitStatusTerminationSignal(linux.SIGILL))
|
||||
return CtrlDoExit, linuxerr.EFAULT
|
||||
}
|
||||
|
||||
alt := t.SignalStack()
|
||||
if oldaddr != 0 {
|
||||
if _, err := alt.CopyOut(t, oldaddr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if setaddr != 0 {
|
||||
if _, err := alt.CopyIn(t, setaddr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// The signal stack cannot be changed if the task is currently
|
||||
// on the stack. This is enforced at the lowest level because
|
||||
// these semantics apply to changing the signal stack via a
|
||||
// ucontext during a signal handler.
|
||||
if !t.SetSignalStack(alt) {
|
||||
return nil, linuxerr.EPERM
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// onSignalStack returns true if the task is executing on the given signal stack.
|
||||
func (t *Task) onSignalStack(alt linux.SignalStack) bool {
|
||||
sp := hostarch.Addr(t.Arch().Stack())
|
||||
@@ -1018,7 +1047,10 @@ func (*runInterrupt) execute(t *Task) taskRunState {
|
||||
|
||||
// Are there signals pending?
|
||||
if info := t.dequeueSignalLocked(linux.SignalSet(t.signalMask.RacyLoad())); info != nil {
|
||||
t.p.PullFullState(t.MemoryManager().AddressSpace(), t.Arch())
|
||||
if err := t.p.PullFullState(t.MemoryManager().AddressSpace(), t.Arch()); err != nil {
|
||||
t.PrepareGroupExit(linux.WaitStatusTerminationSignal(linux.SIGILL))
|
||||
return (*runExit)(nil)
|
||||
}
|
||||
|
||||
if linux.SignalSetOf(linux.Signal(info.Signo))&StopSignals != 0 {
|
||||
// Indicate that we've dequeued a stop signal before unlocking the
|
||||
|
||||
@@ -125,7 +125,7 @@ func (c *context) Release() {}
|
||||
func (c *context) FullStateChanged() {}
|
||||
|
||||
// PullFullState implements platform.Context.PullFullState.
|
||||
func (c *context) PullFullState(as platform.AddressSpace, ac *arch.Context64) {}
|
||||
func (c *context) PullFullState(as platform.AddressSpace, ac *arch.Context64) error { return nil }
|
||||
|
||||
// PrepareSleep implements platform.Context.platform.Context.
|
||||
func (*context) PrepareSleep() {}
|
||||
|
||||
@@ -221,7 +221,7 @@ type Context interface {
|
||||
// PullFullState() to load all registers and FPU state.
|
||||
//
|
||||
// Preconditions: The caller must be running on the task goroutine.
|
||||
PullFullState(as AddressSpace, ac *arch.Context64)
|
||||
PullFullState(as AddressSpace, ac *arch.Context64) error
|
||||
|
||||
// FullStateChanged() indicates that a thread state has been changed by
|
||||
// the Sentry. This happens in case of the rt_sigreturn, execve, etc.
|
||||
|
||||
@@ -197,7 +197,7 @@ func (c *context) Release() {}
|
||||
func (c *context) FullStateChanged() {}
|
||||
|
||||
// PullFullState implements platform.Context.PullFullState.
|
||||
func (c *context) PullFullState(as platform.AddressSpace, ac *arch.Context64) {}
|
||||
func (c *context) PullFullState(as platform.AddressSpace, ac *arch.Context64) error { return nil }
|
||||
|
||||
// PrepareSleep implements platform.Context.platform.PrepareSleep.
|
||||
func (*context) PrepareSleep() {}
|
||||
|
||||
@@ -323,26 +323,8 @@ func Sigaltstack(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.S
|
||||
setaddr := args[0].Pointer()
|
||||
oldaddr := args[1].Pointer()
|
||||
|
||||
alt := t.SignalStack()
|
||||
if oldaddr != 0 {
|
||||
if _, err := alt.CopyOut(t, oldaddr); err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
}
|
||||
if setaddr != 0 {
|
||||
if _, err := alt.CopyIn(t, setaddr); err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
// The signal stack cannot be changed if the task is currently
|
||||
// on the stack. This is enforced at the lowest level because
|
||||
// these semantics apply to changing the signal stack via a
|
||||
// ucontext during a signal handler.
|
||||
if !t.SetSignalStack(alt) {
|
||||
return 0, nil, linuxerr.EPERM
|
||||
}
|
||||
}
|
||||
|
||||
return 0, nil, nil
|
||||
ctrl, err := t.SigaltStack(setaddr, oldaddr)
|
||||
return 0, ctrl, err
|
||||
}
|
||||
|
||||
// Pause implements linux syscall pause(2).
|
||||
|
||||
Reference in New Issue
Block a user