diff options
author | Nicolas Lacasse <nlacasse@google.com> | 2019-07-02 12:53:47 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2019-07-02 12:58:58 -0700 |
commit | 4f2f44320f9b96bdc8c0fb25c116104ea501ab8b (patch) | |
tree | 824e354b27eeb0e932fc3c6f9cadec869674fbf7 | |
parent | 0aa9418a778b2fffef4ea4691e97868b498e3b22 (diff) |
Simplify (and fix) refcounts in createAt.
fileOpAt holds references on the Dirents passed as arguments to the callback,
and drops refs when finished, so we don't need to DecRef those Dirents
ourselves
However, all Dirents that we get from FindInode/FindLink must be DecRef'd.
This CL cleans up the ref-counting logic, and fixes some refcount issues in the
process.
PiperOrigin-RevId: 256220882
-rw-r--r-- | pkg/sentry/syscalls/linux/sys_file.go | 17 |
1 files changed, 8 insertions, 9 deletions
diff --git a/pkg/sentry/syscalls/linux/sys_file.go b/pkg/sentry/syscalls/linux/sys_file.go index 3410af69c..2776fdec7 100644 --- a/pkg/sentry/syscalls/linux/sys_file.go +++ b/pkg/sentry/syscalls/linux/sys_file.go @@ -326,6 +326,7 @@ func createAt(t *kernel.Task, dirFD kdefs.FD, addr usermem.Addr, flags uint, mod if err != nil { break } + defer found.DecRef() // We found something (possibly a symlink). If the // O_EXCL flag was passed, then we can immediately @@ -346,17 +347,18 @@ func createAt(t *kernel.Task, dirFD kdefs.FD, addr usermem.Addr, flags uint, mod } // Try to resolve the symlink directly to a Dirent. - resolved, err := found.Inode.Getlink(t) - if err == nil || err != fs.ErrResolveViaReadlink { + var resolved *fs.Dirent + resolved, err = found.Inode.Getlink(t) + if err == nil { // No more resolution necessary. - found.DecRef() - found = resolved + defer resolved.DecRef() break + } else if err != fs.ErrResolveViaReadlink { + return err } // Are we able to resolve further? if remainingTraversals == 0 { - found.DecRef() return syscall.ELOOP } @@ -373,10 +375,10 @@ func createAt(t *kernel.Task, dirFD kdefs.FD, addr usermem.Addr, flags uint, mod if err != nil { break } + defer newParent.DecRef() // Repeat the process with the parent and name of the // symlink target. - parent.DecRef() parent = newParent name = newName } @@ -384,9 +386,6 @@ func createAt(t *kernel.Task, dirFD kdefs.FD, addr usermem.Addr, flags uint, mod var newFile *fs.File switch err { case nil: - // The file existed. - defer found.DecRef() - // Like sys_open, check for a few things about the // filesystem before trying to get a reference to the // fs.File. The same constraints on Check apply. |