Skip to content

Commit

Permalink
kernel: only lock TaskSet.mu in Task.unstopVforkParent() if necessary
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 687421394
  • Loading branch information
nixprime authored and gvisor-bot committed Oct 18, 2024
1 parent babeb34 commit 0b59173
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 9 deletions.
10 changes: 9 additions & 1 deletion pkg/sentry/kernel/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ type Task struct {
// this TaskImage is released.
//
// vforkParent is protected by the TaskSet mutex.
vforkParent *Task
vforkParent atomic.Pointer[Task] `state:".(*Task)"`

// exitState is the task's progress through the exit path.
//
Expand Down Expand Up @@ -631,6 +631,14 @@ var (
})
)

func (t *Task) saveVforkParent() *Task {
return t.vforkParent.Load()
}

func (t *Task) loadVforkParent(_ gocontext.Context, vforkParent *Task) {
t.vforkParent.Store(vforkParent)
}

func (t *Task) savePtraceTracer() *Task {
return t.ptraceTracer.Load()
}
Expand Down
22 changes: 14 additions & 8 deletions pkg/sentry/kernel/task_clone.go
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ func (t *Task) Clone(args *linux.CloneArgs) (ThreadID, *SyscallControl, error) {
nt.seccomp.Store(nil)
}
if args.Flags&linux.CLONE_VFORK != 0 {
nt.vforkParent = t
nt.vforkParent.Store(t)
}

if args.Flags&linux.CLONE_CHILD_CLEARTID != 0 {
Expand Down Expand Up @@ -396,30 +396,36 @@ func getCloneSeccheckInfo(t, nt *Task, flags uint64) (seccheck.FieldSet, *pb.Clo
//
// Preconditions: The caller must be running on t's task goroutine.
func (t *Task) maybeBeginVforkStop(child *Task) {
if child.vforkParent.Load() != t {
return
}
t.tg.pidns.owner.mu.Lock()
defer t.tg.pidns.owner.mu.Unlock()
t.tg.signalHandlers.mu.Lock()
defer t.tg.signalHandlers.mu.Unlock()
if t.killedLocked() {
child.vforkParent = nil
if child.vforkParent.Load() != t {
return
}
if child.vforkParent == t {
t.beginInternalStopLocked((*vforkStop)(nil))
if t.killedLocked() {
child.vforkParent.Store(nil)
return
}
t.beginInternalStopLocked((*vforkStop)(nil))
}

func (t *Task) unstopVforkParent() {
if t.vforkParent.Load() == nil {
return
}
t.tg.pidns.owner.mu.Lock()
defer t.tg.pidns.owner.mu.Unlock()
if p := t.vforkParent; p != nil {
if p := t.vforkParent.Load(); p != nil {
t.vforkParent.Store(nil)
p.tg.signalHandlers.mu.Lock()
defer p.tg.signalHandlers.mu.Unlock()
if _, ok := p.stop.(*vforkStop); ok {
p.endInternalStopLocked()
}
// Parent no longer needs to be unstopped.
t.vforkParent = nil
}
}

Expand Down

0 comments on commit 0b59173

Please sign in to comment.