Skip to content

Commit c91c52f

Browse files
committed
Merge pull request #12055 from tianyuzhou95:albert/refcount
PiperOrigin-RevId: 800675291
2 parents 093d944 + 512b9a4 commit c91c52f

File tree

3 files changed

+23
-14
lines changed

3 files changed

+23
-14
lines changed

pkg/sentry/control/lifecycle.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121

2222
"google.golang.org/protobuf/types/known/timestamppb"
2323
"gvisor.dev/gvisor/pkg/abi/linux"
24+
"gvisor.dev/gvisor/pkg/cleanup"
2425
"gvisor.dev/gvisor/pkg/eventchannel"
2526
"gvisor.dev/gvisor/pkg/fd"
2627
"gvisor.dev/gvisor/pkg/log"
@@ -288,6 +289,8 @@ func (l *Lifecycle) StartContainer(args *StartContainerArgs, _ *uint32) error {
288289

289290
initArgs.MountNamespace = mntns
290291
initArgs.MountNamespace.IncRef()
292+
mntnsCu := cleanup.Make(func() { initArgs.MountNamespace.DecRef(ctx) })
293+
defer mntnsCu.Clean()
291294

292295
if args.ResolveBinaryPath {
293296
resolved, err := user.ResolveExecutablePath(ctx, &initArgs)
@@ -327,6 +330,7 @@ func (l *Lifecycle) StartContainer(args *StartContainerArgs, _ *uint32) error {
327330
}
328331
initArgs.InitialCgroups = initialCgroups
329332

333+
mntnsCu.Release() // mntns ref is transferred to Kernel.CreateProcess()
330334
tg, _, err := l.Kernel.CreateProcess(initArgs)
331335
if err != nil {
332336
return err

pkg/sentry/control/proc.go

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"time"
2626

2727
"gvisor.dev/gvisor/pkg/abi/linux"
28+
"gvisor.dev/gvisor/pkg/cleanup"
2829
"gvisor.dev/gvisor/pkg/fd"
2930
"gvisor.dev/gvisor/pkg/log"
3031
"gvisor.dev/gvisor/pkg/sentry/fdimport"
@@ -217,13 +218,18 @@ func (proc *Proc) execAsync(args *ExecArgs) (*kernel.ThreadGroup, kernel.ThreadI
217218
PIDNamespace: pidns,
218219
Origin: kernel.OriginExec,
219220
}
220-
if initArgs.MountNamespace != nil {
221-
// initArgs must hold a reference on MountNamespace, which will
222-
// be donated to the new process in CreateProcess.
223-
initArgs.MountNamespace.IncRef()
224-
}
225221
ctx := initArgs.NewContext(proc.Kernel)
226222

223+
if initArgs.MountNamespace == nil {
224+
// Set initArgs so that 'ctx' returns the namespace.
225+
initArgs.MountNamespace = proc.Kernel.GlobalInit().Leader().MountNamespace()
226+
}
227+
// initArgs must hold a reference on MountNamespace, which will
228+
// be donated to the new process in CreateProcess.
229+
initArgs.MountNamespace.IncRef()
230+
mntnsCu := cleanup.Make(func() { initArgs.MountNamespace.DecRef(ctx) })
231+
defer mntnsCu.Clean()
232+
227233
// Import file descriptors.
228234
var fdTable *kernel.FDTable
229235
if args.FDTable != nil {
@@ -235,15 +241,6 @@ func (proc *Proc) execAsync(args *ExecArgs) (*kernel.ThreadGroup, kernel.ThreadI
235241
}
236242
initArgs.FDTable = fdTable
237243

238-
// Get the full path to the filename from the PATH env variable.
239-
if initArgs.MountNamespace == nil {
240-
// Set initArgs so that 'ctx' returns the namespace.
241-
//
242-
// Add a reference to the namespace, which is transferred to the new process.
243-
initArgs.MountNamespace = proc.Kernel.GlobalInit().Leader().MountNamespace()
244-
initArgs.MountNamespace.IncRef()
245-
}
246-
247244
fdMap, execFD, err := args.unpackFiles()
248245
if err != nil {
249246
return nil, 0, nil, fmt.Errorf("creating fd map: %w", err)
@@ -311,6 +308,7 @@ func (proc *Proc) execAsync(args *ExecArgs) (*kernel.ThreadGroup, kernel.ThreadI
311308
initArgs.InitialCgroups = initialCgrps
312309
}
313310

311+
mntnsCu.Release() // mntns ref is transferred to Kernel.CreateProcess()
314312
tg, tid, err := proc.Kernel.CreateProcess(initArgs)
315313
if err != nil {
316314
return nil, 0, nil, err

pkg/sentry/kernel/kernel.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,6 +1038,9 @@ func (ctx *createProcessContext) getMemoryCgroupID() uint32 {
10381038
//
10391039
// CreateProcess has no analogue in Linux; it is used to create the initial
10401040
// application task, as well as processes started by the control server.
1041+
//
1042+
// Precondition: Caller must take a ref on args.MountNamespace, which is
1043+
// transferred to CreateProcess.
10411044
func (k *Kernel) CreateProcess(args CreateProcessArgs) (*ThreadGroup, ThreadID, error) {
10421045
k.extMu.Lock()
10431046
defer k.extMu.Unlock()
@@ -1056,6 +1059,8 @@ func (k *Kernel) CreateProcess(args CreateProcessArgs) (*ThreadGroup, ThreadID,
10561059
// Get the root directory from the MountNamespace.
10571060
root := mntns.Root(ctx)
10581061
defer root.DecRef(ctx)
1062+
refcountCu := cleanup.Make(func() { mntns.DecRef(ctx) })
1063+
defer refcountCu.Clean()
10591064

10601065
// Grab the working directory.
10611066
wd := root // Default.
@@ -1081,6 +1086,7 @@ func (k *Kernel) CreateProcess(args CreateProcessArgs) (*ThreadGroup, ThreadID,
10811086
defer wd.DecRef(ctx)
10821087
}
10831088
fsContext := NewFSContext(root, wd, args.Umask)
1089+
refcountCu.Add(func() { fsContext.DecRef(ctx) })
10841090

10851091
tg := k.NewThreadGroup(args.PIDNamespace, NewSignalHandlers(), linux.SIGCHLD, args.Limits)
10861092
cu := cleanup.Make(func() {
@@ -1156,6 +1162,7 @@ func (k *Kernel) CreateProcess(args CreateProcessArgs) (*ThreadGroup, ThreadID,
11561162
config.UTSNamespace.IncRef()
11571163
config.IPCNamespace.IncRef()
11581164
config.NetworkNamespace.IncRef()
1165+
refcountCu.Release() // refs(mntns, fsContext) are transferred to NewTask()
11591166
t, err := k.tasks.NewTask(ctx, config)
11601167
if err != nil {
11611168
return nil, 0, err

0 commit comments

Comments
 (0)