From 22961a9e41a141b70d1ffa0fc02c00efe93801be Mon Sep 17 00:00:00 2001 From: Ayush Ranjan Date: Tue, 24 Jan 2023 11:14:25 -0800 Subject: [PATCH] Make kernfs.walkParentDirLocked() start path traversal from passed dentry. This is analogous to all other filesystem implementations and their walkParentDirLocked() implementations. This is required because sometimes walkParentDirLocked() is called after symlinks are followed. And the traversal should continue from the parent of the symlink file. PiperOrigin-RevId: 504326573 --- pkg/sentry/fsimpl/kernfs/filesystem.go | 28 +++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/pkg/sentry/fsimpl/kernfs/filesystem.go b/pkg/sentry/fsimpl/kernfs/filesystem.go index 8bf4192dd..f6d5a8a72 100644 --- a/pkg/sentry/fsimpl/kernfs/filesystem.go +++ b/pkg/sentry/fsimpl/kernfs/filesystem.go @@ -180,8 +180,7 @@ func (fs *Filesystem) walkExistingLocked(ctx context.Context, rp *vfs.ResolvingP // - !rp.Done(). // // Postconditions: Caller must call fs.processDeferredDecRefs*. -func (fs *Filesystem) walkParentDirLocked(ctx context.Context, rp *vfs.ResolvingPath) (*Dentry, error) { - d := rp.Start().Impl().(*Dentry) +func (fs *Filesystem) walkParentDirLocked(ctx context.Context, rp *vfs.ResolvingPath, d *Dentry) (*Dentry, error) { for !rp.Final() { var err error d, _, err = fs.stepExistingLocked(ctx, rp, d) @@ -342,7 +341,7 @@ func (fs *Filesystem) GetParentDentryAt(ctx context.Context, rp *vfs.ResolvingPa fs.mu.RLock() defer fs.processDeferredDecRefs(ctx) defer fs.mu.RUnlock() - d, err := fs.walkParentDirLocked(ctx, rp) + d, err := fs.walkParentDirLocked(ctx, rp, rp.Start().Impl().(*Dentry)) if err != nil { return nil, err } @@ -358,7 +357,7 @@ func (fs *Filesystem) LinkAt(ctx context.Context, rp *vfs.ResolvingPath, vd vfs. fs.mu.Lock() defer fs.processDeferredDecRefs(ctx) defer fs.mu.Unlock() - parent, err := fs.walkParentDirLocked(ctx, rp) + parent, err := fs.walkParentDirLocked(ctx, rp, rp.Start().Impl().(*Dentry)) if err != nil { return err } @@ -405,7 +404,7 @@ func (fs *Filesystem) MkdirAt(ctx context.Context, rp *vfs.ResolvingPath, opts v fs.mu.Lock() defer fs.processDeferredDecRefs(ctx) defer fs.mu.Unlock() - parent, err := fs.walkParentDirLocked(ctx, rp) + parent, err := fs.walkParentDirLocked(ctx, rp, rp.Start().Impl().(*Dentry)) if err != nil { return err } @@ -442,7 +441,7 @@ func (fs *Filesystem) MknodAt(ctx context.Context, rp *vfs.ResolvingPath, opts v fs.mu.Lock() defer fs.processDeferredDecRefs(ctx) defer fs.mu.Unlock() - parent, err := fs.walkParentDirLocked(ctx, rp) + parent, err := fs.walkParentDirLocked(ctx, rp, rp.Start().Impl().(*Dentry)) if err != nil { return err } @@ -499,7 +498,7 @@ func (fs *Filesystem) OpenAt(ctx context.Context, rp *vfs.ResolvingPath, opts vf // May create new file. mustCreate := opts.Flags&linux.O_EXCL != 0 - d := rp.Start().Impl().(*Dentry) + start := rp.Start().Impl().(*Dentry) fs.mu.Lock() unlocked := false unlock := func() { @@ -520,19 +519,19 @@ func (fs *Filesystem) OpenAt(ctx context.Context, rp *vfs.ResolvingPath, opts vf if mustCreate { return nil, linuxerr.EEXIST } - if err := d.inode.CheckPermissions(ctx, rp.Credentials(), ats); err != nil { + if err := start.inode.CheckPermissions(ctx, rp.Credentials(), ats); err != nil { return nil, err } // Open may block so we need to unlock fs.mu. IncRef d to prevent // its destruction while fs.mu is unlocked. - d.IncRef() + start.IncRef() unlock() - fd, err := d.inode.Open(ctx, rp, d, opts) - d.DecRef(ctx) + fd, err := start.inode.Open(ctx, rp, start, opts) + start.DecRef(ctx) return fd, err } afterTrailingSymlink: - parent, err := fs.walkParentDirLocked(ctx, rp) + parent, err := fs.walkParentDirLocked(ctx, rp, start) if err != nil { return nil, err } @@ -566,6 +565,7 @@ afterTrailingSymlink: // must be handled by the VFS layer. return nil, err } + start = parent goto afterTrailingSymlink } if linuxerr.Equals(linuxerr.ENOENT, err) { @@ -660,7 +660,7 @@ func (fs *Filesystem) RenameAt(ctx context.Context, rp *vfs.ResolvingPath, oldPa // Resolve the destination directory first to verify that it's on this // Mount. - dstDir, err := fs.walkParentDirLocked(ctx, rp) + dstDir, err := fs.walkParentDirLocked(ctx, rp, rp.Start().Impl().(*Dentry)) if err != nil { return err } @@ -883,7 +883,7 @@ func (fs *Filesystem) SymlinkAt(ctx context.Context, rp *vfs.ResolvingPath, targ fs.mu.Lock() defer fs.processDeferredDecRefs(ctx) defer fs.mu.Unlock() - parent, err := fs.walkParentDirLocked(ctx, rp) + parent, err := fs.walkParentDirLocked(ctx, rp, rp.Start().Impl().(*Dentry)) if err != nil { return err }