diff options
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/sentry/fs/proc/mounts.go | 15 | ||||
-rw-r--r-- | pkg/sentry/kernel/fs_context.go | 17 | ||||
-rw-r--r-- | pkg/sentry/kernel/task_resources.go | 4 |
3 files changed, 29 insertions, 7 deletions
diff --git a/pkg/sentry/fs/proc/mounts.go b/pkg/sentry/fs/proc/mounts.go index b9988625e..108432f4e 100644 --- a/pkg/sentry/fs/proc/mounts.go +++ b/pkg/sentry/fs/proc/mounts.go @@ -28,9 +28,22 @@ import ( // forEachMountSource runs f for the process root mount and each mount that is a // descendant of the root. func forEachMountSource(t *kernel.Task, fn func(string, *fs.MountSource)) { + var fsctx *kernel.FSContext + t.WithMuLocked(func(t *kernel.Task) { + fsctx = t.FSContext() + }) + if fsctx == nil { + // The task has been destroyed. Nothing to show here. + return + } + // All mount points must be relative to the rootDir, and mounts outside // will be excluded. - rootDir := t.FSContext().RootDirectory() + rootDir := fsctx.RootDirectory() + if rootDir == nil { + // The task has been destroyed. Nothing to show here. + return + } defer rootDir.DecRef() if rootDir.Inode == nil { diff --git a/pkg/sentry/kernel/fs_context.go b/pkg/sentry/kernel/fs_context.go index d1ca9c09d..dbc097696 100644 --- a/pkg/sentry/kernel/fs_context.go +++ b/pkg/sentry/kernel/fs_context.go @@ -66,6 +66,11 @@ func newFSContext(root, cwd *fs.Dirent, umask uint) *FSContext { // (that return nil). This is because valid references may still be held via // proc files or other mechanisms. func (f *FSContext) destroy() { + // Hold f.mu so that we don't race with RootDirectory() and + // WorkingDirectory(). + f.mu.Lock() + defer f.mu.Unlock() + f.root.DecRef() f.root = nil @@ -94,9 +99,9 @@ func (f *FSContext) Fork() *FSContext { } // WorkingDirectory returns the current working directory. -// You should call DecRef on the returned Dirent when finished. // -// This will return nil if called after destroy(). +// This will return nil if called after destroy(), otherwise it will return a +// Dirent with a reference taken. func (f *FSContext) WorkingDirectory() *fs.Dirent { f.mu.Lock() defer f.mu.Unlock() @@ -129,13 +134,15 @@ func (f *FSContext) SetWorkingDirectory(d *fs.Dirent) { } // RootDirectory returns the current filesystem root. -// You should call DecRef on the returned Dirent when finished. // -// This will return nil if called after destroy(). +// This will return nil if called after destroy(), otherwise it will return a +// Dirent with a reference taken. func (f *FSContext) RootDirectory() *fs.Dirent { f.mu.Lock() defer f.mu.Unlock() - f.root.IncRef() + if f.root != nil { + f.root.IncRef() + } return f.root } diff --git a/pkg/sentry/kernel/task_resources.go b/pkg/sentry/kernel/task_resources.go index 0389989e8..4ca25664a 100644 --- a/pkg/sentry/kernel/task_resources.go +++ b/pkg/sentry/kernel/task_resources.go @@ -123,6 +123,8 @@ func (t *Task) IsChrooted() bool { realRoot := t.k.mounts.Root() defer realRoot.DecRef() root := t.tr.FSContext.RootDirectory() - defer root.DecRef() + if root != nil { + defer root.DecRef() + } return root != realRoot } |