diff --git a/pkg/sentry/kernel/ptrace.go b/pkg/sentry/kernel/ptrace.go index 17ac1b56a..a8c591146 100644 --- a/pkg/sentry/kernel/ptrace.go +++ b/pkg/sentry/kernel/ptrace.go @@ -317,7 +317,7 @@ func (t *Task) SetYAMAException(tracer *Task) { // Tracer returns t's ptrace Tracer. func (t *Task) Tracer() *Task { - return t.ptraceTracer.Load().(*Task) + return t.ptraceTracer.Load() } // hasTracer returns true if t has a ptrace tracer attached. @@ -605,7 +605,7 @@ func (t *Task) forgetTracerLocked() { t.ptraceOpts = ptraceOptions{} t.ptraceSyscallMode = ptraceSyscallNone t.ptraceSinglestep = false - t.ptraceTracer.Store((*Task)(nil)) + t.ptraceTracer.Store(nil) if t.exitTracerNotified && !t.exitTracerAcked { t.exitTracerAcked = true t.exitNotifyLocked(true) diff --git a/pkg/sentry/kernel/task.go b/pkg/sentry/kernel/task.go index c0af03092..4b0a131a4 100644 --- a/pkg/sentry/kernel/task.go +++ b/pkg/sentry/kernel/task.go @@ -319,15 +319,13 @@ type Task struct { goroutineStopped sync.WaitGroup `state:"nosave"` // ptraceTracer is the task that is ptrace-attached to this one. If - // ptraceTracer is nil, this task is not being traced. Note that due to - // atomic.Value limitations (atomic.Value.Store(nil) panics), a nil - // ptraceTracer is always represented as a typed nil (i.e. (*Task)(nil)). + // ptraceTracer is nil, this task is not being traced. // // ptraceTracer is protected by the TaskSet mutex, and accessed with atomic // operations. This allows paths that wouldn't otherwise lock the TaskSet // mutex, notably the syscall path, to check if ptraceTracer is nil without // additional synchronization. - ptraceTracer atomic.Value `state:".(*Task)"` + ptraceTracer atomic.Pointer[Task] `state:".(*Task)"` // ptraceTracees is the set of tasks that this task is ptrace-attached to. // @@ -616,7 +614,7 @@ var ( ) func (t *Task) savePtraceTracer() *Task { - return t.ptraceTracer.Load().(*Task) + return t.ptraceTracer.Load() } func (t *Task) loadPtraceTracer(tracer *Task) { diff --git a/pkg/sentry/kernel/task_exit.go b/pkg/sentry/kernel/task_exit.go index 0bca6a294..c4d9c8c6e 100644 --- a/pkg/sentry/kernel/task_exit.go +++ b/pkg/sentry/kernel/task_exit.go @@ -1111,7 +1111,7 @@ func (t *Task) waitCollectZombieLocked(target *Task, opts *WaitOptions, asPtrace // will be reaped here. if tracer := target.Tracer(); tracer != nil && tracer.tg == t.tg && target.exitTracerNotified { target.exitTracerAcked = true - target.ptraceTracer.Store((*Task)(nil)) + target.ptraceTracer.Store(nil) delete(t.ptraceTracees, target) } if target.parent != nil && target.parent.tg == t.tg && target.exitParentNotified { diff --git a/pkg/sentry/kernel/task_start.go b/pkg/sentry/kernel/task_start.go index bb6a0606c..c5cb5411a 100644 --- a/pkg/sentry/kernel/task_start.go +++ b/pkg/sentry/kernel/task_start.go @@ -176,7 +176,6 @@ func (ts *TaskSet) newTask(ctx context.Context, cfg *TaskConfig) (*Task, error) t.netns = cfg.NetworkNamespace t.creds.Store(cfg.Credentials) t.endStopCond.L = &t.tg.signalHandlers.mu - t.ptraceTracer.Store((*Task)(nil)) t.seccomp.Store((*taskSeccomp)(nil)) // We don't construct t.blockingTimer until Task.run(); see that function // for justification.