diff options
author | Fabricio Voznika <fvoznika@google.com> | 2018-11-01 17:51:22 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-11-01 17:52:11 -0700 |
commit | 5cd55cd90fd5a32685807a57617cde6f5f76d22b (patch) | |
tree | 626eaac23c76d63ef1917bb7e3e51fb618d20f7e | |
parent | b6b81fd04ba93db3268ff649c9d23a25c9b89db5 (diff) |
Use spec with clean paths for gofer
Otherwise the gofer's attach point may be different from sandbox when there
symlinks in the path.
PiperOrigin-RevId: 219730492
Change-Id: Ia9c4c2d16228c6a1a9e790e0cb673fd881003fe1
-rw-r--r-- | runsc/boot/loader_test.go | 5 | ||||
-rw-r--r-- | runsc/cmd/gofer.go | 21 | ||||
-rw-r--r-- | runsc/container/container.go | 3 | ||||
-rw-r--r-- | runsc/fsgofer/fsgofer.go | 24 | ||||
-rw-r--r-- | runsc/fsgofer/fsgofer_test.go | 20 |
5 files changed, 52 insertions, 21 deletions
diff --git a/runsc/boot/loader_test.go b/runsc/boot/loader_test.go index c342ee005..d5cee5608 100644 --- a/runsc/boot/loader_test.go +++ b/runsc/boot/loader_test.go @@ -77,8 +77,11 @@ func startGofer(root string) (int, func(), error) { syscall.Close(goferEnd) return 0, nil, fmt.Errorf("error creating server on FD %d: %v", goferEnd, err) } + at, err := fsgofer.NewAttachPoint(root, fsgofer.Config{ROMount: true}) + if err != nil { + return 0, nil, err + } go func() { - at := fsgofer.NewAttachPoint(root, fsgofer.Config{ROMount: true}) s := p9.NewServer(at) if err := s.Handle(socket); err != nil { log.Infof("Gofer is stopping. FD: %d, err: %v\n", goferEnd, err) diff --git a/runsc/cmd/gofer.go b/runsc/cmd/gofer.go index 7cc666e10..4ec3dba9c 100644 --- a/runsc/cmd/gofer.go +++ b/runsc/cmd/gofer.go @@ -99,7 +99,12 @@ func (g *Gofer) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) panic("unreachable") } - spec, err := specutils.ReadSpec(g.bundleDir) + specFile, err := specutils.OpenCleanSpec(g.bundleDir) + if err != nil { + Fatalf("error opening spec: %v", err) + } + spec, err := specutils.ReadSpecFromFile(g.bundleDir, specFile) + specFile.Close() if err != nil { Fatalf("error reading spec: %v", err) } @@ -121,10 +126,14 @@ func (g *Gofer) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) // Start with root mount, then add any other additional mount as needed. ats := make([]p9.Attacher, 0, len(spec.Mounts)+1) - ats = append(ats, fsgofer.NewAttachPoint("/", fsgofer.Config{ + ap, err := fsgofer.NewAttachPoint("/", fsgofer.Config{ ROMount: spec.Root.Readonly, PanicOnWrite: g.panicOnWrite, - })) + }) + if err != nil { + Fatalf("Error creating attach point: %v", err) + } + ats = append(ats, ap) log.Infof("Serving %q mapped to %q on FD %d (ro: %t)", "/", root, g.ioFDs[0], spec.Root.Readonly) mountIdx := 1 // first one is the root @@ -134,7 +143,11 @@ func (g *Gofer) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) ROMount: isReadonlyMount(m.Options), PanicOnWrite: g.panicOnWrite, } - ats = append(ats, fsgofer.NewAttachPoint(m.Destination, cfg)) + ap, err := fsgofer.NewAttachPoint(m.Destination, cfg) + if err != nil { + Fatalf("Error creating attach point: %v", err) + } + ats = append(ats, ap) if mountIdx >= len(g.ioFDs) { Fatalf("No FD found for mount. Did you forget --io-fd? mount: %d, %v", len(g.ioFDs), m) diff --git a/runsc/container/container.go b/runsc/container/container.go index 9da25a863..4c542ccb9 100644 --- a/runsc/container/container.go +++ b/runsc/container/container.go @@ -374,6 +374,9 @@ func (c *Container) Start(conf *boot.Config) error { return fmt.Errorf("setup mounts: %v", err) } c.Spec.Mounts = cleanMounts + if err := specutils.WriteCleanSpec(c.BundleDir, c.Spec); err != nil { + return fmt.Errorf("writing clean spec: %v", err) + } // Create the gofer process. ioFiles, err := c.createGoferProcess(c.Spec, conf, c.BundleDir) diff --git a/runsc/fsgofer/fsgofer.go b/runsc/fsgofer/fsgofer.go index 4412d7e2f..b5746447f 100644 --- a/runsc/fsgofer/fsgofer.go +++ b/runsc/fsgofer/fsgofer.go @@ -26,6 +26,7 @@ import ( "math" "os" "path" + "path/filepath" "sync" "syscall" @@ -99,24 +100,28 @@ type attachPoint struct { } // NewAttachPoint creates a new attacher that gives local file -// access to all files under 'prefix'. -func NewAttachPoint(prefix string, c Config) p9.Attacher { +// access to all files under 'prefix'. 'prefix' must be an absolute path. +func NewAttachPoint(prefix string, c Config) (p9.Attacher, error) { + // Sanity check the prefix. + if !filepath.IsAbs(prefix) { + return nil, fmt.Errorf("attach point prefix must be absolute %q", prefix) + } return &attachPoint{ prefix: prefix, conf: c, devices: make(map[uint64]uint8), - } + }, nil } // Attach implements p9.Attacher. func (a *attachPoint) Attach() (p9.File, error) { - // Sanity check the prefix. - fi, err := os.Stat(a.prefix) + // dirFD (1st argument) is ignored because 'prefix' is always absolute. + stat, err := statAt(-1, a.prefix) if err != nil { - return nil, err + return nil, fmt.Errorf("stat file %q, err: %v", a.prefix, err) } mode := os.O_RDWR - if a.conf.ROMount || fi.IsDir() { + if a.conf.ROMount || stat.Mode&syscall.S_IFDIR != 0 { mode = os.O_RDONLY } @@ -125,11 +130,6 @@ func (a *attachPoint) Attach() (p9.File, error) { if err != nil { return nil, fmt.Errorf("unable to open file %q, err: %v", a.prefix, err) } - stat, err := stat(int(f.Fd())) - if err != nil { - f.Close() - return nil, fmt.Errorf("failed to stat file %q, err: %v", a.prefix, err) - } a.attachedMu.Lock() defer a.attachedMu.Unlock() diff --git a/runsc/fsgofer/fsgofer_test.go b/runsc/fsgofer/fsgofer_test.go index f799b1e25..47b5380dc 100644 --- a/runsc/fsgofer/fsgofer_test.go +++ b/runsc/fsgofer/fsgofer_test.go @@ -80,7 +80,10 @@ func runCustom(t *testing.T, types []fileType, confs []Config, test func(*testin } defer os.RemoveAll(path) - a := NewAttachPoint(path, c) + a, err := NewAttachPoint(path, c) + if err != nil { + t.Fatalf("NewAttachPoint failed: %v", err) + } root, err := a.Attach() if err != nil { t.Fatalf("Attach failed, err: %v", err) @@ -107,7 +110,10 @@ func setup(ft fileType) (string, string, error) { } // First attach with writable configuration to setup tree. - a := NewAttachPoint(path, Config{}) + a, err := NewAttachPoint(path, Config{}) + if err != nil { + return "", "", err + } root, err := a.Attach() if err != nil { return "", "", fmt.Errorf("Attach failed, err: %v", err) @@ -556,7 +562,10 @@ func TestAttachFile(t *testing.T) { t.Fatalf("os.Create(%q) failed, err: %v", path, err) } - a := NewAttachPoint(path, conf) + a, err := NewAttachPoint(path, conf) + if err != nil { + t.Fatalf("NewAttachPoint failed: %v", err) + } root, err := a.Attach() if err != nil { t.Fatalf("Attach failed, err: %v", err) @@ -595,7 +604,10 @@ func TestDoubleAttachError(t *testing.T) { t.Fatalf("ioutil.TempDir() failed, err: %v", err) } defer os.RemoveAll(root) - a := NewAttachPoint(root, conf) + a, err := NewAttachPoint(root, conf) + if err != nil { + t.Fatalf("NewAttachPoint failed: %v", err) + } if _, err := a.Attach(); err != nil { t.Fatalf("Attach failed: %v", err) |