summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorZyad A. Ali <zyad.ali.me@gmail.com>2021-06-02 15:54:36 +0200
committerZyad A. Ali <zyad.ali.me@gmail.com>2021-07-13 22:12:02 +0200
commit4a874557f5846ec9cb2e5b2515921e37a4ca4f07 (patch)
treef8e3f5d9b1ec5b8f003fb8185e03df3effb394fd
parent084aa4fa51b74b426cf1bc0e1347624b2b516bcd (diff)
Implement stubs for msgget(2) and msgctl(IPC_RMID).
Add support for msgget, and msgctl(IPC_RMID), and enable msgqueue syscall tests. Updates #135
-rw-r--r--pkg/sentry/kernel/msgqueue/msgqueue.go5
-rw-r--r--pkg/sentry/syscalls/linux/BUILD1
-rw-r--r--pkg/sentry/syscalls/linux/linux64.go16
-rw-r--r--pkg/sentry/syscalls/linux/sys_msgqueue.go57
-rw-r--r--test/syscalls/linux/msgqueue.cc9
5 files changed, 71 insertions, 17 deletions
diff --git a/pkg/sentry/kernel/msgqueue/msgqueue.go b/pkg/sentry/kernel/msgqueue/msgqueue.go
index 5f7f35cd3..3ce926950 100644
--- a/pkg/sentry/kernel/msgqueue/msgqueue.go
+++ b/pkg/sentry/kernel/msgqueue/msgqueue.go
@@ -213,3 +213,8 @@ func (q *Queue) Destroy() {
q.senders.Notify(waiter.EventOut)
q.receivers.Notify(waiter.EventIn)
}
+
+// ID returns queue's ID.
+func (q *Queue) ID() ipc.ID {
+ return q.obj.ID
+}
diff --git a/pkg/sentry/syscalls/linux/BUILD b/pkg/sentry/syscalls/linux/BUILD
index 7941b2be9..ccccce6a9 100644
--- a/pkg/sentry/syscalls/linux/BUILD
+++ b/pkg/sentry/syscalls/linux/BUILD
@@ -25,6 +25,7 @@ go_library(
"sys_mempolicy.go",
"sys_mmap.go",
"sys_mount.go",
+ "sys_msgqueue.go",
"sys_pipe.go",
"sys_poll.go",
"sys_prctl.go",
diff --git a/pkg/sentry/syscalls/linux/linux64.go b/pkg/sentry/syscalls/linux/linux64.go
index f1cb5a2c8..6f44d767b 100644
--- a/pkg/sentry/syscalls/linux/linux64.go
+++ b/pkg/sentry/syscalls/linux/linux64.go
@@ -121,10 +121,10 @@ var AMD64 = &kernel.SyscallTable{
65: syscalls.PartiallySupported("semop", Semop, "Option SEM_UNDO not supported.", nil),
66: syscalls.Supported("semctl", Semctl),
67: syscalls.Supported("shmdt", Shmdt),
- 68: syscalls.ErrorWithEvent("msgget", syserror.ENOSYS, "", []string{"gvisor.dev/issue/135"}), // TODO(b/29354921)
- 69: syscalls.ErrorWithEvent("msgsnd", syserror.ENOSYS, "", []string{"gvisor.dev/issue/135"}), // TODO(b/29354921)
- 70: syscalls.ErrorWithEvent("msgrcv", syserror.ENOSYS, "", []string{"gvisor.dev/issue/135"}), // TODO(b/29354921)
- 71: syscalls.ErrorWithEvent("msgctl", syserror.ENOSYS, "", []string{"gvisor.dev/issue/135"}), // TODO(b/29354921)
+ 68: syscalls.Supported("msgget", Msgget),
+ 69: syscalls.ErrorWithEvent("msgsnd", linuxerr.ENOSYS, "", []string{"gvisor.dev/issue/135"}), // TODO(b/29354921)
+ 70: syscalls.ErrorWithEvent("msgrcv", linuxerr.ENOSYS, "", []string{"gvisor.dev/issue/135"}), // TODO(b/29354921)
+ 71: syscalls.PartiallySupported("msgctl", Msgctl, "Only supports IPC_RMID option.", []string{"gvisor.dev/issue/135"}),
72: syscalls.PartiallySupported("fcntl", Fcntl, "Not all options are supported.", nil),
73: syscalls.PartiallySupported("flock", Flock, "Locks are held within the sandbox only.", nil),
74: syscalls.PartiallySupported("fsync", Fsync, "Full data flush is not guaranteed at this time.", nil),
@@ -616,10 +616,10 @@ var ARM64 = &kernel.SyscallTable{
183: syscalls.ErrorWithEvent("mq_timedreceive", syserror.ENOSYS, "", []string{"gvisor.dev/issue/136"}), // TODO(b/29354921)
184: syscalls.ErrorWithEvent("mq_notify", syserror.ENOSYS, "", []string{"gvisor.dev/issue/136"}), // TODO(b/29354921)
185: syscalls.ErrorWithEvent("mq_getsetattr", syserror.ENOSYS, "", []string{"gvisor.dev/issue/136"}), // TODO(b/29354921)
- 186: syscalls.ErrorWithEvent("msgget", syserror.ENOSYS, "", []string{"gvisor.dev/issue/135"}), // TODO(b/29354921)
- 187: syscalls.ErrorWithEvent("msgctl", syserror.ENOSYS, "", []string{"gvisor.dev/issue/135"}), // TODO(b/29354921)
- 188: syscalls.ErrorWithEvent("msgrcv", syserror.ENOSYS, "", []string{"gvisor.dev/issue/135"}), // TODO(b/29354921)
- 189: syscalls.ErrorWithEvent("msgsnd", syserror.ENOSYS, "", []string{"gvisor.dev/issue/135"}), // TODO(b/29354921)
+ 186: syscalls.Supported("msgget", Msgget),
+ 187: syscalls.PartiallySupported("msgctl", Msgctl, "Only supports IPC_RMID option.", []string{"gvisor.dev/issue/135"}),
+ 188: syscalls.ErrorWithEvent("msgrcv", linuxerr.ENOSYS, "", []string{"gvisor.dev/issue/135"}), // TODO(b/29354921)
+ 189: syscalls.ErrorWithEvent("msgsnd", linuxerr.ENOSYS, "", []string{"gvisor.dev/issue/135"}), // TODO(b/29354921)
190: syscalls.Supported("semget", Semget),
191: syscalls.Supported("semctl", Semctl),
192: syscalls.Supported("semtimedop", Semtimedop),
diff --git a/pkg/sentry/syscalls/linux/sys_msgqueue.go b/pkg/sentry/syscalls/linux/sys_msgqueue.go
new file mode 100644
index 000000000..3476e218d
--- /dev/null
+++ b/pkg/sentry/syscalls/linux/sys_msgqueue.go
@@ -0,0 +1,57 @@
+// 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 linux
+
+import (
+ "gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/errors/linuxerr"
+ "gvisor.dev/gvisor/pkg/sentry/arch"
+ "gvisor.dev/gvisor/pkg/sentry/kernel"
+ "gvisor.dev/gvisor/pkg/sentry/kernel/auth"
+ "gvisor.dev/gvisor/pkg/sentry/kernel/ipc"
+)
+
+// Msgget implements msgget(2).
+func Msgget(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
+ key := ipc.Key(args[0].Int())
+ flag := args[1].Int()
+
+ private := key == linux.IPC_PRIVATE
+ create := flag&linux.IPC_CREAT == linux.IPC_CREAT
+ exclusive := flag&linux.IPC_EXCL == linux.IPC_EXCL
+ mode := linux.FileMode(flag & 0777)
+
+ r := t.IPCNamespace().MsgqueueRegistry()
+ queue, err := r.FindOrCreate(t, key, mode, private, create, exclusive)
+ if err != nil {
+ return 0, nil, err
+ }
+ return uintptr(queue.ID()), nil, nil
+}
+
+// Msgctl implements msgctl(2).
+func Msgctl(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
+ id := ipc.ID(args[0].Int())
+ cmd := args[1].Int()
+
+ creds := auth.CredentialsFromContext(t)
+
+ switch cmd {
+ case linux.IPC_RMID:
+ return 0, nil, t.IPCNamespace().MsgqueueRegistry().Remove(id, creds)
+ default:
+ return 0, nil, linuxerr.EINVAL
+ }
+}
diff --git a/test/syscalls/linux/msgqueue.cc b/test/syscalls/linux/msgqueue.cc
index ba61bba34..2409de7e8 100644
--- a/test/syscalls/linux/msgqueue.cc
+++ b/test/syscalls/linux/msgqueue.cc
@@ -48,9 +48,6 @@ class Queue {
// Test simple creation and retrieval for msgget(2).
TEST(MsgqueueTest, MsgGet) {
- // Don't run test until syscall is implemented.
- GTEST_SKIP();
-
const TempPath keyfile = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
const key_t key = ftok(keyfile.path().c_str(), 1);
ASSERT_THAT(key, SyscallSucceeds());
@@ -62,9 +59,6 @@ TEST(MsgqueueTest, MsgGet) {
// Test simple failure scenarios for msgget(2).
TEST(MsgqueueTest, MsgGetFail) {
- // Don't run test until syscall is implemented.
- GTEST_SKIP();
-
const TempPath keyfile = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
const key_t key = ftok(keyfile.path().c_str(), 1);
ASSERT_THAT(key, SyscallSucceeds());
@@ -79,9 +73,6 @@ TEST(MsgqueueTest, MsgGetFail) {
// Test using msgget(2) with IPC_PRIVATE option.
TEST(MsgqueueTest, MsgGetIpcPrivate) {
- // Don't run test until syscall is implemented.
- GTEST_SKIP();
-
Queue queue1(msgget(IPC_PRIVATE, 0));
ASSERT_THAT(queue1.get(), SyscallSucceeds());