diff options
Diffstat (limited to 'pkg/sentry/syscalls')
-rw-r--r-- | pkg/sentry/syscalls/linux/vfs2/BUILD | 2 | ||||
-rw-r--r-- | pkg/sentry/syscalls/linux/vfs2/mq.go | 98 | ||||
-rw-r--r-- | pkg/sentry/syscalls/linux/vfs2/vfs2.go | 5 |
3 files changed, 104 insertions, 1 deletions
diff --git a/pkg/sentry/syscalls/linux/vfs2/BUILD b/pkg/sentry/syscalls/linux/vfs2/BUILD index 1e3bd2a50..4a03008f8 100644 --- a/pkg/sentry/syscalls/linux/vfs2/BUILD +++ b/pkg/sentry/syscalls/linux/vfs2/BUILD @@ -19,6 +19,7 @@ go_library( "memfd.go", "mmap.go", "mount.go", + "mq.go", "path.go", "pipe.go", "poll.go", @@ -59,6 +60,7 @@ go_library( "//pkg/sentry/kernel", "//pkg/sentry/kernel/auth", "//pkg/sentry/kernel/fasync", + "//pkg/sentry/kernel/mq", "//pkg/sentry/kernel/pipe", "//pkg/sentry/kernel/time", "//pkg/sentry/limits", diff --git a/pkg/sentry/syscalls/linux/vfs2/mq.go b/pkg/sentry/syscalls/linux/vfs2/mq.go new file mode 100644 index 000000000..d5d81c6e2 --- /dev/null +++ b/pkg/sentry/syscalls/linux/vfs2/mq.go @@ -0,0 +1,98 @@ +// Copyright 2021 The gVisor Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package vfs2 + +import ( + "gvisor.dev/gvisor/pkg/abi/linux" + "gvisor.dev/gvisor/pkg/sentry/arch" + "gvisor.dev/gvisor/pkg/sentry/kernel" + "gvisor.dev/gvisor/pkg/sentry/kernel/mq" +) + +// MqOpen implements mq_open(2). +func MqOpen(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + nameAddr := args[0].Pointer() + flag := args[1].Int() + mode := args[2].ModeT() + attrAddr := args[3].Pointer() + + name, err := t.CopyInString(nameAddr, mq.MaxName) + if err != nil { + return 0, nil, err + } + + rOnly := flag&linux.O_RDONLY == linux.O_RDONLY + wOnly := flag&linux.O_WRONLY == linux.O_WRONLY + readWrite := flag&linux.O_RDWR == linux.O_RDWR + + create := flag&linux.O_CREAT == linux.O_CREAT + exclusive := flag&linux.O_EXCL == linux.O_EXCL + block := flag&linux.O_NONBLOCK != linux.O_NONBLOCK + + var attr linux.MqAttr + var attrPtr *linux.MqAttr + if attrAddr != 0 { + if _, err := attr.CopyIn(t, attrAddr); err != nil { + return 0, nil, err + } + attrPtr = &attr + } + + opts := openOpts(name, rOnly, wOnly, readWrite, create, exclusive, block) + + r := t.IPCNamespace().PosixQueues() + queue, err := r.FindOrCreate(t, opts, linux.FileMode(mode), attrPtr) + if err != nil { + return 0, nil, err + } + + fd, err := t.NewFDFromVFS2(0, queue, kernel.FDFlags{ + CloseOnExec: flag&linux.O_CLOEXEC != 0, + }) + if err != nil { + return 0, nil, err + } + return uintptr(fd), nil, nil +} + +// MqUnlink implements mq_unlink(2). +func MqUnlink(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { + nameAddr := args[0].Pointer() + name, err := t.CopyInString(nameAddr, mq.MaxName) + if err != nil { + return 0, nil, err + } + return 0, nil, t.IPCNamespace().PosixQueues().Remove(t, name) +} + +func openOpts(name string, rOnly, wOnly, readWrite, create, exclusive, block bool) mq.OpenOpts { + var access mq.AccessType + switch { + case readWrite: + access = mq.ReadWrite + case wOnly: + access = mq.WriteOnly + case rOnly: + access = mq.ReadOnly + } + + return mq.OpenOpts{ + Name: name, + Access: access, + Create: create, + Exclusive: exclusive, + Block: block, + } +} diff --git a/pkg/sentry/syscalls/linux/vfs2/vfs2.go b/pkg/sentry/syscalls/linux/vfs2/vfs2.go index 0fc81e694..4eb15a7f2 100644 --- a/pkg/sentry/syscalls/linux/vfs2/vfs2.go +++ b/pkg/sentry/syscalls/linux/vfs2/vfs2.go @@ -112,6 +112,8 @@ func Override() { s.Table[232] = syscalls.Supported("epoll_wait", EpollWait) s.Table[233] = syscalls.Supported("epoll_ctl", EpollCtl) s.Table[235] = syscalls.Supported("utimes", Utimes) + s.Table[240] = syscalls.Supported("mq_open", MqOpen) + s.Table[241] = syscalls.Supported("mq_unlink", MqUnlink) s.Table[253] = syscalls.PartiallySupported("inotify_init", InotifyInit, "inotify events are only available inside the sandbox.", nil) s.Table[254] = syscalls.PartiallySupported("inotify_add_watch", InotifyAddWatch, "inotify events are only available inside the sandbox.", nil) s.Table[255] = syscalls.PartiallySupported("inotify_rm_watch", InotifyRmWatch, "inotify events are only available inside the sandbox.", nil) @@ -241,6 +243,8 @@ func Override() { s.Table[86] = syscalls.Supported("timerfd_settime", TimerfdSettime) s.Table[87] = syscalls.Supported("timerfd_gettime", TimerfdGettime) s.Table[88] = syscalls.Supported("utimensat", Utimensat) + s.Table[180] = syscalls.Supported("mq_open", MqOpen) + s.Table[181] = syscalls.Supported("mq_unlink", MqUnlink) s.Table[198] = syscalls.Supported("socket", Socket) s.Table[199] = syscalls.Supported("socketpair", SocketPair) s.Table[200] = syscalls.Supported("bind", Bind) @@ -271,6 +275,5 @@ func Override() { s.Table[287] = syscalls.Supported("pwritev2", Pwritev2) s.Table[291] = syscalls.Supported("statx", Statx) s.Table[441] = syscalls.Supported("epoll_pwait2", EpollPwait2) - s.Init() } |