From 0842a94cd00aa8ffcb0e61b7f0191bd56f5754d2 Mon Sep 17 00:00:00 2001 From: Ayush Ranjan Date: Tue, 4 Oct 2022 16:49:41 -0700 Subject: [PATCH] Lisafs gofer should not allow walk/mount on pipes. Fixes #8045 PiperOrigin-RevId: 478915103 --- runsc/fsgofer/lisafs.go | 22 ++++++++++++++++++++++ test/e2e/BUILD | 1 + test/e2e/integration_test.go | 26 ++++++++++++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/runsc/fsgofer/lisafs.go b/runsc/fsgofer/lisafs.go index cba36f220..2b76d6d1c 100644 --- a/runsc/fsgofer/lisafs.go +++ b/runsc/fsgofer/lisafs.go @@ -60,12 +60,22 @@ func (s *LisafsServer) Mount(c *lisafs.Connection, mountNode *lisafs.Node) (*lis if err != nil { return nil, linux.Statx{}, err } + cu := cleanup.Make(func() { + _ = unix.Close(rootHostFD) + }) + defer cu.Clean() stat, err := fstatTo(rootHostFD) if err != nil { return nil, linux.Statx{}, err } + if err := checkSupportedFileType(uint32(stat.Mode), s.config.HostUDS); err != nil { + log.Warningf("Mount: checkSupportedFileType() failed for file %q with mode %o: %v", mountPath, stat.Mode, err) + return nil, linux.Statx{}, err + } + cu.Release() + rootFD := &controlFDLisa{ hostFD: rootHostFD, writableHostFD: atomicbitops.FromInt32(-1), @@ -327,6 +337,13 @@ func (fd *controlFDLisa) Walk(name string) (*lisafs.ControlFD, linux.Statx, erro stat, err := fstatTo(childHostFD) if err != nil { + _ = unix.Close(childHostFD) + return nil, linux.Statx{}, err + } + + if err := checkSupportedFileType(uint32(stat.Mode), fd.Conn().ServerImpl().(*LisafsServer).config.HostUDS); err != nil { + _ = unix.Close(childHostFD) + log.Warningf("Walk: checkSupportedFileType() failed for %q with mode %o: %v", name, stat.Mode, err) return nil, linux.Statx{}, err } @@ -361,6 +378,7 @@ func (fd *controlFDLisa) WalkStat(path lisafs.StringArray, recordStat func(linux if fd.IsSymlink() { return nil } + server := fd.Conn().ServerImpl().(*LisafsServer) for _, name := range path { curFD, err := unix.Openat(curDirFD, name, unix.O_PATH|openFlags, 0) if err == unix.ENOENT { @@ -378,6 +396,10 @@ func (fd *controlFDLisa) WalkStat(path lisafs.StringArray, recordStat func(linux if err != nil { return err } + if err := checkSupportedFileType(uint32(stat.Mode), server.config.HostUDS); err != nil { + log.Warningf("WalkStat: checkSupportedFileType() failed for file %q with mode %o while walking path %+v: %v", name, stat.Mode, path, err) + return err + } recordStat(stat) // Symlinks terminate walk. This client gets the symlink stat result, but diff --git a/test/e2e/BUILD b/test/e2e/BUILD index d9f71f838..225569276 100644 --- a/test/e2e/BUILD +++ b/test/e2e/BUILD @@ -23,6 +23,7 @@ go_test( "//pkg/test/testutil", "//runsc/specutils", "@com_github_docker_docker//api/types/mount:go_default_library", + "@org_golang_x_sys//unix:go_default_library", ], ) diff --git a/test/e2e/integration_test.go b/test/e2e/integration_test.go index 8caf32eb8..10e531003 100644 --- a/test/e2e/integration_test.go +++ b/test/e2e/integration_test.go @@ -30,6 +30,7 @@ import ( "net/http" "os" "os/exec" + "path" "path/filepath" "regexp" "strconv" @@ -38,6 +39,7 @@ import ( "time" "github.com/docker/docker/api/types/mount" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/test/dockerutil" "gvisor.dev/gvisor/pkg/test/testutil" ) @@ -997,3 +999,27 @@ func TestNonSearchableWorkingDirectory(t *testing.T) { t.Errorf("ls error message not found, want: %q, got: %q", wantErrorMsg, got) } } + +func TestPipeMountFails(t *testing.T) { + ctx := context.Background() + d := dockerutil.MakeContainer(ctx, t) + defer d.CleanUp(ctx) + + fifoPath := path.Join(testutil.TmpDir(), "fifo") + if err := unix.Mkfifo(fifoPath, 0666); err != nil { + t.Fatalf("Mkfifo(%q) failed: %v", fifoPath, err) + } + opts := dockerutil.RunOpts{ + Image: "basic/alpine", + Mounts: []mount.Mount{ + { + Type: mount.TypeBind, + Source: fifoPath, + Target: "/foo", + }, + }, + } + if _, err := d.Run(ctx, opts, "ls"); err == nil { + t.Errorf("docker run succeded, but mounting a named pipe should not work") + } +}