summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNicolas Lacasse <nlacasse@google.com>2019-07-02 12:53:47 -0700
committergVisor bot <gvisor-bot@google.com>2019-07-02 12:58:58 -0700
commit4f2f44320f9b96bdc8c0fb25c116104ea501ab8b (patch)
tree824e354b27eeb0e932fc3c6f9cadec869674fbf7
parent0aa9418a778b2fffef4ea4691e97868b498e3b22 (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.go17
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.