@@ -18,7 +18,6 @@ import (
1818 "context"
1919 "fmt"
2020 "os"
21- "os/exec"
2221 "path/filepath"
2322 "runtime"
2423 "runtime/debug"
@@ -44,6 +43,7 @@ import (
4443 "gvisor.dev/gvisor/pkg/sentry/syscalls/linux"
4544 "gvisor.dev/gvisor/pkg/tcpip/nftables"
4645 "gvisor.dev/gvisor/runsc/boot"
46+ "gvisor.dev/gvisor/runsc/cmd/sandboxsetup"
4747 "gvisor.dev/gvisor/runsc/cmd/util"
4848 "gvisor.dev/gvisor/runsc/config"
4949 "gvisor.dev/gvisor/runsc/flag"
@@ -96,14 +96,14 @@ type Boot struct {
9696 deviceFD int
9797
9898 // ioFDs is the list of FDs used to connect to FS gofers.
99- ioFDs intFlags
99+ ioFDs sandboxsetup. IntFlags
100100
101101 // devIoFD is the FD to connect to dev gofer.
102102 devIoFD int
103103
104104 // goferFilestoreFDs are FDs to the regular files that will back the tmpfs or
105105 // overlayfs mount for certain gofer mounts.
106- goferFilestoreFDs intFlags
106+ goferFilestoreFDs sandboxsetup. IntFlags
107107
108108 // goferMountConfs contains information about how the gofer mounts have been
109109 // configured. The first entry is for rootfs and the following entries are
@@ -112,7 +112,7 @@ type Boot struct {
112112
113113 // stdioFDs are the fds for stdin, stdout, and stderr. They must be
114114 // provided in that order.
115- stdioFDs intFlags
115+ stdioFDs sandboxsetup. IntFlags
116116
117117 // passFDs are mappings of user-supplied host to guest file descriptors.
118118 passFDs fdMappings
@@ -152,11 +152,11 @@ type Boot struct {
152152
153153 podInitConfigFD int
154154
155- sinkFDs intFlags
155+ sinkFDs sandboxsetup. IntFlags
156156
157- saveFDs intFlags
157+ saveFDs sandboxsetup. IntFlags
158158
159- fsRestoreFDs intFlags
159+ fsRestoreFDs sandboxsetup. IntFlags
160160
161161 // attached is set to true to kill the sandbox process when the parent process
162162 // terminates. This flag is set when the command execve's itself because
@@ -385,7 +385,7 @@ func (b *Boot) Execute(_ context.Context, f *flag.FlagSet, args ...any) subcomma
385385 // /proc is umounted from a forked process, because the
386386 // current one is going to re-execute itself without
387387 // capabilities.
388- cmd , w := execProcUmounter ()
388+ cmd , w := sandboxsetup . ExecProcUmounter ()
389389 defer cmd .Wait ()
390390 defer w .Close ()
391391 if b .procMountSyncFD != - 1 {
@@ -402,13 +402,13 @@ func (b *Boot) Execute(_ context.Context, f *flag.FlagSet, args ...any) subcomma
402402
403403 if ! b .applyCaps {
404404 // Remove the args that have already been done before calling self.
405- args := prepareArgs (b .Name (), f , argOverride )
405+ args := sandboxsetup . PrepareArgs (b .Name (), f , argOverride )
406406
407407 // Note that we've already read the spec from the spec FD, and
408408 // we will read it again after the exec call. This works
409409 // because the ReadSpecFromFile function seeks to the beginning
410410 // of the file before reading.
411- util .Fatalf ("callSelfAsNobody(%v): %v" , args , callSelfAsNobody (args ))
411+ util .Fatalf ("callSelfAsNobody(%v): %v" , args , sandboxsetup . CallSelfAsNobody (args ))
412412
413413 // This prevents the specFile finalizer from running and closed
414414 // the specFD, which we have passed to ourselves when
@@ -467,13 +467,13 @@ func (b *Boot) Execute(_ context.Context, f *flag.FlagSet, args ...any) subcomma
467467 argOverride ["apply-caps" ] = "false"
468468
469469 // Remove the args that have already been done before calling self.
470- args := prepareArgs (b .Name (), f , argOverride )
470+ args := sandboxsetup . PrepareArgs (b .Name (), f , argOverride )
471471
472472 // Note that we've already read the spec from the spec FD, and
473473 // we will read it again after the exec call. This works
474474 // because the ReadSpecFromFile function seeks to the beginning
475475 // of the file before reading.
476- util .Fatalf ("setCapsAndCallSelf(%v, %v): %v" , args , caps , setCapsAndCallSelf (args , caps ))
476+ util .Fatalf ("setCapsAndCallSelf(%v, %v): %v" , args , caps , sandboxsetup . SetCapsAndCallSelf (args , caps ))
477477
478478 // This prevents the specFile finalizer from running and closed
479479 // the specFD, which we have passed to ourselves when
@@ -609,7 +609,7 @@ func (b *Boot) Execute(_ context.Context, f *flag.FlagSet, args ...any) subcomma
609609 // Call validateOpenFDs() before umounting /proc.
610610 validateOpenFDs (bootArgs .PassFDs )
611611 // Umount /proc right before installing seccomp filters.
612- umountProc (b .procMountSyncFD )
612+ sandboxsetup . UmountProc (b .procMountSyncFD )
613613 }
614614 }
615615
@@ -671,84 +671,6 @@ func (b *Boot) Execute(_ context.Context, f *flag.FlagSet, args ...any) subcomma
671671 return subcommands .ExitSuccess
672672}
673673
674- // prepareArgs returns the args that can be used to re-execute the current
675- // program. It manipulates the flags of the subcommands.Command identified by
676- // subCmdName and fSet is the flag.FlagSet of this subcommand. It applies the
677- // flags specified by override map. In case of conflict, flag is overridden.
678- //
679- // Postcondition: prepareArgs() takes ownership of override map.
680- func prepareArgs (subCmdName string , fSet * flag.FlagSet , override map [string ]string ) []string {
681- var args []string
682- // Add all args up until (and including) the sub command.
683- for _ , arg := range os .Args {
684- args = append (args , arg )
685- if arg == subCmdName {
686- break
687- }
688- }
689- // Set sub command flags. Iterate through all the explicitly set flags.
690- fSet .Visit (func (gf * flag.Flag ) {
691- // If a conflict is found with override, then prefer override flag.
692- if ov , ok := override [gf .Name ]; ok {
693- args = append (args , fmt .Sprintf ("--%s=%s" , gf .Name , ov ))
694- delete (override , gf .Name )
695- return
696- }
697- // Otherwise pass through the original flag.
698- args = append (args , fmt .Sprintf ("--%s=%s" , gf .Name , gf .Value ))
699- })
700- // Apply remaining override flags (that didn't conflict above).
701- for of , ov := range override {
702- args = append (args , fmt .Sprintf ("--%s=%s" , of , ov ))
703- }
704- // Add the non-flag arguments at the end.
705- args = append (args , fSet .Args ()... )
706- return args
707- }
708-
709- // execProcUmounter execute a child process that umounts /proc when the
710- // returned pipe is closed.
711- func execProcUmounter () (* exec.Cmd , * os.File ) {
712- r , w , err := os .Pipe ()
713- if err != nil {
714- util .Fatalf ("error creating a pipe: %v" , err )
715- }
716- defer r .Close ()
717-
718- cmd := exec .Command (specutils .ExePath )
719- cmd .Args = append (cmd .Args , "umount" , "--sync-fd=3" , "/proc" )
720- cmd .ExtraFiles = append (cmd .ExtraFiles , r )
721- cmd .Stdin = os .Stdin
722- cmd .Stdout = os .Stdout
723- cmd .Stderr = os .Stderr
724- if err := cmd .Start (); err != nil {
725- util .Fatalf ("error executing umounter: %v" , err )
726- }
727- return cmd , w
728- }
729-
730- // umountProc writes to syncFD signalling the process started by
731- // execProcUmounter() to umount /proc.
732- func umountProc (syncFD int ) {
733- syncFile := os .NewFile (uintptr (syncFD ), "procfs umount sync FD" )
734- buf := make ([]byte , 1 )
735- if w , err := syncFile .Write (buf ); err != nil || w != 1 {
736- util .Fatalf ("unable to write into the proc umounter descriptor: %v" , err )
737- }
738- syncFile .Close ()
739-
740- var waitStatus unix.WaitStatus
741- if _ , err := unix .Wait4 (0 , & waitStatus , 0 , nil ); err != nil {
742- util .Fatalf ("error waiting for the proc umounter process: %v" , err )
743- }
744- if ! waitStatus .Exited () || waitStatus .ExitStatus () != 0 {
745- util .Fatalf ("the proc umounter process failed: %v" , waitStatus )
746- }
747- if err := unix .Access ("/proc/self" , unix .F_OK ); err != unix .ENOENT {
748- util .Fatalf ("/proc is still accessible" )
749- }
750- }
751-
752674// validateOpenFDs checks that the sandbox process does not have any open
753675// directory FDs.
754676func validateOpenFDs (passFDs []boot.FDMapping ) {
0 commit comments