From f5d0c59f5c736f5f7fceb566e134f41b03229c22 Mon Sep 17 00:00:00 2001 From: Ian Gudger Date: Wed, 13 Jun 2018 20:00:00 -0700 Subject: [PATCH] Fix reference leak in VDSO validation PiperOrigin-RevId: 200496070 Change-Id: I33adb717c44e5b4bcadece882be3ab1ee3920556 --- pkg/sentry/fs/dirent.go | 5 +++++ pkg/sentry/loader/BUILD | 1 + pkg/sentry/loader/vdso.go | 20 +++++++++++++++++++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/pkg/sentry/fs/dirent.go b/pkg/sentry/fs/dirent.go index 554aa30d8..b56437b3c 100644 --- a/pkg/sentry/fs/dirent.go +++ b/pkg/sentry/fs/dirent.go @@ -213,7 +213,12 @@ func NewDirent(inode *Inode, name string) *Dirent { // NewTransientDirent creates a transient Dirent that shouldn't actually be // visible to users. +// +// An Inode is required. func NewTransientDirent(inode *Inode) *Dirent { + if inode == nil { + panic("an inode is required") + } return newDirent(inode, "transient") } diff --git a/pkg/sentry/loader/BUILD b/pkg/sentry/loader/BUILD index 917ec8cc8..08cb3a777 100644 --- a/pkg/sentry/loader/BUILD +++ b/pkg/sentry/loader/BUILD @@ -43,6 +43,7 @@ go_library( "//pkg/sentry/arch", "//pkg/sentry/context", "//pkg/sentry/fs", + "//pkg/sentry/fs/anon", "//pkg/sentry/fs/fsutil", "//pkg/sentry/limits", "//pkg/sentry/memmap", diff --git a/pkg/sentry/loader/vdso.go b/pkg/sentry/loader/vdso.go index ce4f6f5d9..037576e41 100644 --- a/pkg/sentry/loader/vdso.go +++ b/pkg/sentry/loader/vdso.go @@ -20,10 +20,12 @@ import ( "io" "gvisor.googlesource.com/gvisor/pkg/abi" + "gvisor.googlesource.com/gvisor/pkg/abi/linux" "gvisor.googlesource.com/gvisor/pkg/log" "gvisor.googlesource.com/gvisor/pkg/sentry/arch" "gvisor.googlesource.com/gvisor/pkg/sentry/context" "gvisor.googlesource.com/gvisor/pkg/sentry/fs" + "gvisor.googlesource.com/gvisor/pkg/sentry/fs/anon" "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" "gvisor.googlesource.com/gvisor/pkg/sentry/memmap" "gvisor.googlesource.com/gvisor/pkg/sentry/mm" @@ -63,8 +65,23 @@ func (f *fileContext) Value(key interface{}) interface{} { } } +// newByteReaderFile creates a fake file to read data from. func newByteReaderFile(data []byte) *fs.File { - dirent := fs.NewTransientDirent(nil) + // Create a fake inode. + inode := fs.NewInode(fsutil.NewSimpleInodeOperations(fsutil.InodeSimpleAttributes{ + FSType: linux.ANON_INODE_FS_MAGIC, + }), fs.NewNonCachingMountSource(nil, fs.MountSourceFlags{}), fs.StableAttr{ + Type: fs.Anonymous, + DeviceID: anon.PseudoDevice.DeviceID(), + InodeID: anon.PseudoDevice.NextIno(), + BlockSize: usermem.PageSize, + }) + + // Use the fake inode to create a fake dirent. + dirent := fs.NewTransientDirent(inode) + defer dirent.DecRef() + + // Use the fake dirent to make a fake file. flags := fs.FileFlags{Read: true, Pread: true} return fs.NewFile(&fileContext{Context: context.Background()}, dirent, flags, &byteReader{ data: data, @@ -202,6 +219,7 @@ func PrepareVDSO(p platform.Platform) (*VDSO, error) { // First make sure the VDSO is valid. vdsoFile does not use ctx, so a // nil context can be passed. info, err := validateVDSO(nil, vdsoFile, uint64(len(vdsoBin))) + vdsoFile.DecRef() if err != nil { return nil, err }