Implement stubs for msgget(2) and msgctl(IPC_RMID).

Add support for msgget, and msgctl(IPC_RMID), and enable msgqueue
syscall tests.

Updates #135
This commit is contained in:
Zyad A. Ali
2021-07-13 22:12:02 +02:00
parent 084aa4fa51
commit 4a874557f5
5 changed files with 71 additions and 17 deletions
+5
View File
@@ -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
}
+1
View File
@@ -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",
+8 -8
View File
@@ -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),
+57
View File
@@ -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
}
}
-9
View File
@@ -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());