summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/syscalls/linux/vfs2/fd.go
diff options
context:
space:
mode:
authorDean Deng <deandeng@google.com>2020-07-01 08:40:31 -0700
committergVisor bot <gvisor-bot@google.com>2020-07-01 08:42:12 -0700
commitcda2979b63fad37a33706f8aa430664a9c4d0b3b (patch)
treec8842b932e519733af30a77945a1c0d6c2d7569e /pkg/sentry/syscalls/linux/vfs2/fd.go
parentb8f165ab1cb4d4345d8a25f95a5bc0fece2d49c7 (diff)
Complete async signal delivery support in vfs2.
- Support FIOASYNC, FIO{SET,GET}OWN, SIOC{G,S}PGRP (refactor getting/setting owner in the process). - Unset signal recipient when setting owner with pid == 0 and valid owner type. Updates #2923. PiperOrigin-RevId: 319231420
Diffstat (limited to 'pkg/sentry/syscalls/linux/vfs2/fd.go')
-rw-r--r--pkg/sentry/syscalls/linux/vfs2/fd.go54
1 files changed, 33 insertions, 21 deletions
diff --git a/pkg/sentry/syscalls/linux/vfs2/fd.go b/pkg/sentry/syscalls/linux/vfs2/fd.go
index 7e4c6a56e..517394ba9 100644
--- a/pkg/sentry/syscalls/linux/vfs2/fd.go
+++ b/pkg/sentry/syscalls/linux/vfs2/fd.go
@@ -156,11 +156,10 @@ func Fcntl(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall
}
return uintptr(n), nil, nil
case linux.F_GETOWN:
- a := file.AsyncHandler()
- if a == nil {
+ owner, hasOwner := getAsyncOwner(t, file)
+ if !hasOwner {
return 0, nil, nil
}
- owner := getAsyncOwner(t, a.(*fasync.FileAsync))
if owner.Type == linux.F_OWNER_PGRP {
return uintptr(-owner.PID), nil, nil
}
@@ -176,26 +175,21 @@ func Fcntl(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall
ownerType = linux.F_OWNER_PGRP
who = -who
}
- a := file.SetAsyncHandler(fasync.NewVFS2).(*fasync.FileAsync)
- return 0, nil, setAsyncOwner(t, a, ownerType, who)
+ return 0, nil, setAsyncOwner(t, file, ownerType, who)
case linux.F_GETOWN_EX:
- a := file.AsyncHandler()
- if a == nil {
+ owner, hasOwner := getAsyncOwner(t, file)
+ if !hasOwner {
return 0, nil, nil
}
- addr := args[2].Pointer()
- owner := getAsyncOwner(t, a.(*fasync.FileAsync))
- _, err := t.CopyOut(addr, &owner)
+ _, err := t.CopyOut(args[2].Pointer(), &owner)
return 0, nil, err
case linux.F_SETOWN_EX:
- addr := args[2].Pointer()
var owner linux.FOwnerEx
- n, err := t.CopyIn(addr, &owner)
+ n, err := t.CopyIn(args[2].Pointer(), &owner)
if err != nil {
return 0, nil, err
}
- a := file.SetAsyncHandler(fasync.NewVFS2).(*fasync.FileAsync)
- return uintptr(n), nil, setAsyncOwner(t, a, owner.Type, owner.PID)
+ return uintptr(n), nil, setAsyncOwner(t, file, owner.Type, owner.PID)
case linux.F_GETPIPE_SZ:
pipefile, ok := file.Impl().(*pipe.VFSPipeFD)
if !ok {
@@ -219,30 +213,48 @@ func Fcntl(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall
}
}
-func getAsyncOwner(t *kernel.Task, a *fasync.FileAsync) linux.FOwnerEx {
- ot, otg, opg := a.Owner()
+func getAsyncOwner(t *kernel.Task, fd *vfs.FileDescription) (ownerEx linux.FOwnerEx, hasOwner bool) {
+ a := fd.AsyncHandler()
+ if a == nil {
+ return linux.FOwnerEx{}, false
+ }
+
+ ot, otg, opg := a.(*fasync.FileAsync).Owner()
switch {
case ot != nil:
return linux.FOwnerEx{
Type: linux.F_OWNER_TID,
PID: int32(t.PIDNamespace().IDOfTask(ot)),
- }
+ }, true
case otg != nil:
return linux.FOwnerEx{
Type: linux.F_OWNER_PID,
PID: int32(t.PIDNamespace().IDOfThreadGroup(otg)),
- }
+ }, true
case opg != nil:
return linux.FOwnerEx{
Type: linux.F_OWNER_PGRP,
PID: int32(t.PIDNamespace().IDOfProcessGroup(opg)),
- }
+ }, true
default:
- return linux.FOwnerEx{}
+ return linux.FOwnerEx{}, true
}
}
-func setAsyncOwner(t *kernel.Task, a *fasync.FileAsync, ownerType, pid int32) error {
+func setAsyncOwner(t *kernel.Task, fd *vfs.FileDescription, ownerType, pid int32) error {
+ switch ownerType {
+ case linux.F_OWNER_TID, linux.F_OWNER_PID, linux.F_OWNER_PGRP:
+ // Acceptable type.
+ default:
+ return syserror.EINVAL
+ }
+
+ a := fd.SetAsyncHandler(fasync.NewVFS2).(*fasync.FileAsync)
+ if pid == 0 {
+ a.ClearOwner()
+ return nil
+ }
+
switch ownerType {
case linux.F_OWNER_TID:
task := t.PIDNamespace().TaskWithID(kernel.ThreadID(pid))