From df6a53734659c64fdd09b2dbbc86a305b6dacc48 Mon Sep 17 00:00:00 2001 From: Jamie Liu Date: Wed, 5 Mar 2025 00:17:27 -0800 Subject: [PATCH] Make it possible to pass internal /dev/null via control.Proc.Exec* PiperOrigin-RevId: 733614278 --- pkg/sentry/control/proc.go | 20 +++++++++++++++----- pkg/sentry/devices/memdev/null.go | 5 +++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/pkg/sentry/control/proc.go b/pkg/sentry/control/proc.go index 180214aae..89149d00c 100644 --- a/pkg/sentry/control/proc.go +++ b/pkg/sentry/control/proc.go @@ -132,6 +132,10 @@ type ExecArgs struct { // FilePayload determines the files to give to the new process. FilePayload + // If FDTable is not nil, it is the process FD table. If Exec/ExecAsync + // succeeds, it takes a reference on FDTable. + FDTable *kernel.FDTable + // ContainerID is the container for the process being executed. ContainerID string @@ -178,9 +182,6 @@ func ExecAsync(proc *Proc, args *ExecArgs) (*kernel.ThreadGroup, kernel.ThreadID // newly created thread group and its PID. If the stdio FDs are TTYs, then a // TTYFileOperations that wraps the TTY is also returned. func (proc *Proc) execAsync(args *ExecArgs) (*kernel.ThreadGroup, kernel.ThreadID, *host.TTYFileDescription, error) { - // Import file descriptors. - fdTable := proc.Kernel.NewFDTable() - creds := auth.NewUserCredentials( args.KUID, args.KGID, @@ -203,7 +204,6 @@ func (proc *Proc) execAsync(args *ExecArgs) (*kernel.ThreadGroup, kernel.ThreadI WorkingDirectory: args.WorkingDirectory, MountNamespace: args.MountNamespace, Credentials: creds, - FDTable: fdTable, Umask: 0022, Limits: limitSet, MaxSymlinkTraversals: linux.MaxSymlinkTraversals, @@ -219,7 +219,17 @@ func (proc *Proc) execAsync(args *ExecArgs) (*kernel.ThreadGroup, kernel.ThreadI initArgs.MountNamespace.IncRef() } ctx := initArgs.NewContext(proc.Kernel) - defer fdTable.DecRef(ctx) + + // Import file descriptors. + var fdTable *kernel.FDTable + if args.FDTable != nil { + fdTable = args.FDTable + // reference borrowed from the caller + } else { + fdTable = proc.Kernel.NewFDTable() + defer fdTable.DecRef(ctx) + } + initArgs.FDTable = fdTable // Get the full path to the filename from the PATH env variable. if initArgs.MountNamespace == nil { diff --git a/pkg/sentry/devices/memdev/null.go b/pkg/sentry/devices/memdev/null.go index ff5837747..e450ed14d 100644 --- a/pkg/sentry/devices/memdev/null.go +++ b/pkg/sentry/devices/memdev/null.go @@ -31,6 +31,11 @@ type nullDevice struct{} // Open implements vfs.Device.Open. func (nullDevice) Open(ctx context.Context, mnt *vfs.Mount, vfsd *vfs.Dentry, opts vfs.OpenOptions) (*vfs.FileDescription, error) { + return NewNullFD(ctx, mnt, vfsd, opts) +} + +// NewNullFD returns a vfs.FileDescription for /dev/null. +func NewNullFD(ctx context.Context, mnt *vfs.Mount, vfsd *vfs.Dentry, opts vfs.OpenOptions) (*vfs.FileDescription, error) { fd := &nullFD{} if err := fd.vfsfd.Init(fd, opts.Flags, mnt, vfsd, &vfs.FileDescriptionOptions{ UseDentryMetadata: true,