summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/syscalls/linux
diff options
context:
space:
mode:
authorRahat Mahmood <rahat@google.com>2020-04-23 15:47:59 -0700
committergVisor bot <gvisor-bot@google.com>2020-04-23 15:49:05 -0700
commit93dd47146185ec7004f514e23bad9f225f55efb1 (patch)
tree5df4b95a0b57b3592b79103bf91df0a3a50581a2 /pkg/sentry/syscalls/linux
parent5042ea7e2cbdc0c04fd454583589a3b1e152f95d (diff)
Enable automated marshalling for epoll events.
Ensure we use the correct architecture-specific defintion of epoll event, and use go-marshal for serialization. PiperOrigin-RevId: 308145677
Diffstat (limited to 'pkg/sentry/syscalls/linux')
-rw-r--r--pkg/sentry/syscalls/linux/sys_epoll.go27
-rw-r--r--pkg/sentry/syscalls/linux/vfs2/BUILD1
-rw-r--r--pkg/sentry/syscalls/linux/vfs2/epoll.go7
-rw-r--r--pkg/sentry/syscalls/linux/vfs2/epoll_unsafe.go44
4 files changed, 7 insertions, 72 deletions
diff --git a/pkg/sentry/syscalls/linux/sys_epoll.go b/pkg/sentry/syscalls/linux/sys_epoll.go
index 3ab93fbde..51bf205cf 100644
--- a/pkg/sentry/syscalls/linux/sys_epoll.go
+++ b/pkg/sentry/syscalls/linux/sys_epoll.go
@@ -21,7 +21,6 @@ import (
"gvisor.dev/gvisor/pkg/sentry/kernel/epoll"
"gvisor.dev/gvisor/pkg/sentry/syscalls"
"gvisor.dev/gvisor/pkg/syserror"
- "gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
@@ -72,7 +71,7 @@ func EpollCtl(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sysc
var data [2]int32
if op != linux.EPOLL_CTL_DEL {
var e linux.EpollEvent
- if _, err := t.CopyIn(eventAddr, &e); err != nil {
+ if _, err := e.CopyIn(t, eventAddr); err != nil {
return 0, nil, err
}
@@ -105,28 +104,6 @@ func EpollCtl(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sysc
}
}
-// copyOutEvents copies epoll events from the kernel to user memory.
-func copyOutEvents(t *kernel.Task, addr usermem.Addr, e []epoll.Event) error {
- const itemLen = 12
- buffLen := len(e) * itemLen
- if _, ok := addr.AddLength(uint64(buffLen)); !ok {
- return syserror.EFAULT
- }
-
- b := t.CopyScratchBuffer(buffLen)
- for i := range e {
- usermem.ByteOrder.PutUint32(b[i*itemLen:], e[i].Events)
- usermem.ByteOrder.PutUint32(b[i*itemLen+4:], uint32(e[i].Data[0]))
- usermem.ByteOrder.PutUint32(b[i*itemLen+8:], uint32(e[i].Data[1]))
- }
-
- if _, err := t.CopyOutBytes(addr, b); err != nil {
- return err
- }
-
- return nil
-}
-
// EpollWait implements the epoll_wait(2) linux syscall.
func EpollWait(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
epfd := args[0].Int()
@@ -140,7 +117,7 @@ func EpollWait(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sys
}
if len(r) != 0 {
- if err := copyOutEvents(t, eventsAddr, r); err != nil {
+ if _, err := linux.CopyEpollEventSliceOut(t, eventsAddr, r); err != nil {
return 0, nil, err
}
}
diff --git a/pkg/sentry/syscalls/linux/vfs2/BUILD b/pkg/sentry/syscalls/linux/vfs2/BUILD
index 6ff2d84d2..f6fb0f219 100644
--- a/pkg/sentry/syscalls/linux/vfs2/BUILD
+++ b/pkg/sentry/syscalls/linux/vfs2/BUILD
@@ -6,7 +6,6 @@ go_library(
name = "vfs2",
srcs = [
"epoll.go",
- "epoll_unsafe.go",
"execve.go",
"fd.go",
"filesystem.go",
diff --git a/pkg/sentry/syscalls/linux/vfs2/epoll.go b/pkg/sentry/syscalls/linux/vfs2/epoll.go
index 5a938cee2..34c90ae3e 100644
--- a/pkg/sentry/syscalls/linux/vfs2/epoll.go
+++ b/pkg/sentry/syscalls/linux/vfs2/epoll.go
@@ -28,6 +28,8 @@ import (
"gvisor.dev/gvisor/pkg/waiter"
)
+var sizeofEpollEvent = (*linux.EpollEvent)(nil).SizeBytes()
+
// EpollCreate1 implements Linux syscall epoll_create1(2).
func EpollCreate1(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) {
flags := args[0].Int()
@@ -124,7 +126,7 @@ func EpollWait(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sys
maxEvents := int(args[2].Int())
timeout := int(args[3].Int())
- const _EP_MAX_EVENTS = math.MaxInt32 / sizeofEpollEvent // Linux: fs/eventpoll.c:EP_MAX_EVENTS
+ var _EP_MAX_EVENTS = math.MaxInt32 / sizeofEpollEvent // Linux: fs/eventpoll.c:EP_MAX_EVENTS
if maxEvents <= 0 || maxEvents > _EP_MAX_EVENTS {
return 0, nil, syserror.EINVAL
}
@@ -157,7 +159,8 @@ func EpollWait(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sys
maxEvents -= n
if n != 0 {
// Copy what we read out.
- copiedEvents, err := copyOutEvents(t, eventsAddr, events[:n])
+ copiedBytes, err := linux.CopyEpollEventSliceOut(t, eventsAddr, events[:n])
+ copiedEvents := copiedBytes / sizeofEpollEvent // rounded down
eventsAddr += usermem.Addr(copiedEvents * sizeofEpollEvent)
total += copiedEvents
if err != nil {
diff --git a/pkg/sentry/syscalls/linux/vfs2/epoll_unsafe.go b/pkg/sentry/syscalls/linux/vfs2/epoll_unsafe.go
deleted file mode 100644
index 825f325bf..000000000
--- a/pkg/sentry/syscalls/linux/vfs2/epoll_unsafe.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2020 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 (
- "reflect"
- "runtime"
- "unsafe"
-
- "gvisor.dev/gvisor/pkg/abi/linux"
- "gvisor.dev/gvisor/pkg/gohacks"
- "gvisor.dev/gvisor/pkg/sentry/kernel"
- "gvisor.dev/gvisor/pkg/usermem"
-)
-
-const sizeofEpollEvent = int(unsafe.Sizeof(linux.EpollEvent{}))
-
-func copyOutEvents(t *kernel.Task, addr usermem.Addr, events []linux.EpollEvent) (int, error) {
- if len(events) == 0 {
- return 0, nil
- }
- // Cast events to a byte slice for copying.
- var eventBytes []byte
- eventBytesHdr := (*reflect.SliceHeader)(unsafe.Pointer(&eventBytes))
- eventBytesHdr.Data = uintptr(gohacks.Noescape(unsafe.Pointer(&events[0])))
- eventBytesHdr.Len = len(events) * sizeofEpollEvent
- eventBytesHdr.Cap = len(events) * sizeofEpollEvent
- copiedBytes, err := t.CopyOutBytes(addr, eventBytes)
- runtime.KeepAlive(events)
- copiedEvents := copiedBytes / sizeofEpollEvent // rounded down
- return copiedEvents, err
-}