Skip to content

Commit 0b61c41

Browse files
committed
pkg/sentry: add cleanup to avoid mntns refcount leak
Currently, on certain error paths during task creation (e.g., when "runsc exec" fails), we do not properly handle the refcount of the mount namespace, leading to a refcount leak. This patch adds cleanup that would be released before the reference ownership is transferred to callee, ensuring that the refcount is correctly decremented. Fixes #12054 Signed-off-by: Tianyu Zhou <albert.zty@antgroup.com>
1 parent fc2f4df commit 0b61c41

File tree

3 files changed

+11
-0
lines changed

3 files changed

+11
-0
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() // mnt ns reference is transferred to new process
330334
tg, _, err := l.Kernel.CreateProcess(initArgs)
331335
if err != nil {
332336
return err

pkg/sentry/control/proc.go

Lines changed: 4 additions & 0 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"
@@ -243,6 +244,8 @@ func (proc *Proc) execAsync(args *ExecArgs) (*kernel.ThreadGroup, kernel.ThreadI
243244
initArgs.MountNamespace = proc.Kernel.GlobalInit().Leader().MountNamespace()
244245
initArgs.MountNamespace.IncRef()
245246
}
247+
mntnsCu := cleanup.Make(func() { initArgs.MountNamespace.DecRef(ctx) })
248+
defer mntnsCu.Clean()
246249

247250
fdMap, execFD, err := args.unpackFiles()
248251
if err != nil {
@@ -311,6 +314,7 @@ func (proc *Proc) execAsync(args *ExecArgs) (*kernel.ThreadGroup, kernel.ThreadI
311314
initArgs.InitialCgroups = initialCgrps
312315
}
313316

317+
mntnsCu.Release() // mnt ns reference is transferred to new process
314318
tg, tid, err := proc.Kernel.CreateProcess(initArgs)
315319
if err != nil {
316320
return nil, 0, nil, err

pkg/sentry/kernel/kernel.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,6 +1056,8 @@ func (k *Kernel) CreateProcess(args CreateProcessArgs) (*ThreadGroup, ThreadID,
10561056
// Get the root directory from the MountNamespace.
10571057
root := mntns.Root(ctx)
10581058
defer root.DecRef(ctx)
1059+
mntnsCu := cleanup.Make(func() { mntns.DecRef(ctx) })
1060+
defer mntnsCu.Clean()
10591061

10601062
// Grab the working directory.
10611063
wd := root // Default.
@@ -1156,6 +1158,7 @@ func (k *Kernel) CreateProcess(args CreateProcessArgs) (*ThreadGroup, ThreadID,
11561158
config.UTSNamespace.IncRef()
11571159
config.IPCNamespace.IncRef()
11581160
config.NetworkNamespace.IncRef()
1161+
mntnsCu.Release() // mnt ns reference is transferred to new task
11591162
t, err := k.tasks.NewTask(ctx, config)
11601163
if err != nil {
11611164
return nil, 0, err

0 commit comments

Comments
 (0)