summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJinmou Li <jinmli@google.com>2020-09-03 19:22:24 +0000
committerAndrei Vagin <avagin@gmail.com>2020-09-16 12:19:30 -0700
commit4edc56d3e99b161f2f3311bc22a51012bf0a90ee (patch)
treeac050d771792c8b9f6364b0a3139d2701561a52b
parent826a685a95bec32286688035922a56faf622e87e (diff)
Fix FUSE_RELEASE protocol reply processing
This commit fixes the potential unexpected errors of original handling of FUSE_RELEASE responses while keep the same behavior (ignoring any reply).
-rw-r--r--pkg/sentry/fsimpl/fuse/dev.go9
-rw-r--r--pkg/sentry/fsimpl/fuse/file.go7
2 files changed, 14 insertions, 2 deletions
diff --git a/pkg/sentry/fsimpl/fuse/dev.go b/pkg/sentry/fsimpl/fuse/dev.go
index e7296c189..6f0b896cb 100644
--- a/pkg/sentry/fsimpl/fuse/dev.go
+++ b/pkg/sentry/fsimpl/fuse/dev.go
@@ -204,8 +204,11 @@ func (fd *DeviceFD) readLocked(ctx context.Context, dst usermem.IOSequence, opts
// Fully done with this req, remove it from the queue.
fd.queue.Remove(req)
- if req.hdr.Opcode == linux.FUSE_RELEASE {
+
+ // Remove noReply ones from map of requests expecting a reply.
+ if req.noReply {
fd.numActiveRequests -= 1
+ delete(fd.completions, req.hdr.Unique)
}
return int64(n), nil
@@ -296,6 +299,10 @@ func (fd *DeviceFD) writeLocked(ctx context.Context, src usermem.IOSequence, opt
fut, ok := fd.completions[hdr.Unique]
if !ok {
+ if fut.hdr.Unique == linux.FUSE_RELEASE {
+ // Currently we simply discard the reply for FUSE_RELEASE.
+ return n + src.NumBytes(), nil
+ }
// Server sent us a response for a request we never sent?
return 0, syserror.EINVAL
}
diff --git a/pkg/sentry/fsimpl/fuse/file.go b/pkg/sentry/fsimpl/fuse/file.go
index 15c0e3f41..b98145ba2 100644
--- a/pkg/sentry/fsimpl/fuse/file.go
+++ b/pkg/sentry/fsimpl/fuse/file.go
@@ -84,7 +84,12 @@ func (fd *fileDescription) Release(ctx context.Context) {
}
kernelTask := kernel.TaskFromContext(ctx)
// ignoring errors and FUSE server reply is analogous to Linux's behavior.
- req, _ := conn.NewRequest(auth.CredentialsFromContext(ctx), uint32(kernelTask.ThreadID()), fd.inode().NodeID, opcode, &in)
+ req, err := conn.NewRequest(auth.CredentialsFromContext(ctx), uint32(kernelTask.ThreadID()), fd.inode().NodeID, opcode, &in)
+ if err != nil {
+ // No way to invoke Call() with an errored request.
+ return
+ }
+ req.noReply = true
conn.CallAsync(kernelTask, req)
}