diff --git a/pkg/sentry/devices/tundev/tundev.go b/pkg/sentry/devices/tundev/tundev.go index c331e621d..92d289c22 100644 --- a/pkg/sentry/devices/tundev/tundev.go +++ b/pkg/sentry/devices/tundev/tundev.go @@ -69,7 +69,7 @@ type tunFD struct { } // Ioctl implements vfs.FileDescriptionImpl.Ioctl. -func (fd *tunFD) Ioctl(ctx context.Context, uio usermem.IO, args arch.SyscallArguments) (uintptr, error) { +func (fd *tunFD) Ioctl(ctx context.Context, uio usermem.IO, sysno uintptr, args arch.SyscallArguments) (uintptr, error) { request := args[1].Uint() data := args[2].Pointer() diff --git a/pkg/sentry/fsimpl/devpts/master.go b/pkg/sentry/fsimpl/devpts/master.go index b3945499d..3153229b4 100644 --- a/pkg/sentry/fsimpl/devpts/master.go +++ b/pkg/sentry/fsimpl/devpts/master.go @@ -135,7 +135,7 @@ func (mfd *masterFileDescription) Write(ctx context.Context, src usermem.IOSeque } // Ioctl implements vfs.FileDescriptionImpl.Ioctl. -func (mfd *masterFileDescription) Ioctl(ctx context.Context, io usermem.IO, args arch.SyscallArguments) (uintptr, error) { +func (mfd *masterFileDescription) Ioctl(ctx context.Context, io usermem.IO, sysno uintptr, args arch.SyscallArguments) (uintptr, error) { t := kernel.TaskFromContext(ctx) if t == nil { // ioctl(2) may only be called from a task goroutine. @@ -193,7 +193,7 @@ func (mfd *masterFileDescription) Ioctl(ctx context.Context, io usermem.IO, args } return 0, t.ThreadGroup().SetForegroundProcessGroupID(mfd.t.masterKTTY, kernel.ProcessGroupID(pgid)) default: - maybeEmitUnimplementedEvent(ctx, cmd) + maybeEmitUnimplementedEvent(ctx, sysno, cmd) return 0, linuxerr.ENOTTY } } @@ -212,7 +212,7 @@ func (mfd *masterFileDescription) Stat(ctx context.Context, opts vfs.StatOptions } // maybeEmitUnimplementedEvent emits unimplemented event if cmd is valid. -func maybeEmitUnimplementedEvent(ctx context.Context, cmd uint32) { +func maybeEmitUnimplementedEvent(ctx context.Context, sysno uintptr, cmd uint32) { switch cmd { case linux.TCGETS, linux.TCSETS, @@ -244,6 +244,6 @@ func maybeEmitUnimplementedEvent(ctx context.Context, cmd uint32) { linux.TIOCSSERIAL, linux.TIOCGPTPEER: - unimpl.EmitUnimplementedEvent(ctx) + unimpl.EmitUnimplementedEvent(ctx, sysno) } } diff --git a/pkg/sentry/fsimpl/devpts/replica.go b/pkg/sentry/fsimpl/devpts/replica.go index 98c2e5806..cac44b778 100644 --- a/pkg/sentry/fsimpl/devpts/replica.go +++ b/pkg/sentry/fsimpl/devpts/replica.go @@ -148,7 +148,7 @@ func (rfd *replicaFileDescription) Write(ctx context.Context, src usermem.IOSequ } // Ioctl implements vfs.FileDescriptionImpl.Ioctl. -func (rfd *replicaFileDescription) Ioctl(ctx context.Context, io usermem.IO, args arch.SyscallArguments) (uintptr, error) { +func (rfd *replicaFileDescription) Ioctl(ctx context.Context, io usermem.IO, sysno uintptr, args arch.SyscallArguments) (uintptr, error) { t := kernel.TaskFromContext(ctx) if t == nil { // ioctl(2) may only be called from a task goroutine. @@ -199,7 +199,7 @@ func (rfd *replicaFileDescription) Ioctl(ctx context.Context, io usermem.IO, arg } return 0, t.ThreadGroup().SetForegroundProcessGroupID(rfd.inode.t.replicaKTTY, kernel.ProcessGroupID(pgid)) default: - maybeEmitUnimplementedEvent(ctx, cmd) + maybeEmitUnimplementedEvent(ctx, sysno, cmd) return 0, linuxerr.ENOTTY } } diff --git a/pkg/sentry/fsimpl/host/host.go b/pkg/sentry/fsimpl/host/host.go index e1b5788d2..b32d2be8d 100644 --- a/pkg/sentry/fsimpl/host/host.go +++ b/pkg/sentry/fsimpl/host/host.go @@ -967,7 +967,7 @@ func (f *fileDescription) Epollable() bool { } // Ioctl queries the underlying FD for allowed ioctl commands. -func (f *fileDescription) Ioctl(ctx context.Context, uio usermem.IO, args arch.SyscallArguments) (uintptr, error) { +func (f *fileDescription) Ioctl(ctx context.Context, uio usermem.IO, sysno uintptr, args arch.SyscallArguments) (uintptr, error) { switch cmd := args[1].Int(); cmd { case linux.FIONREAD: v, err := ioctlFionread(f.inode.hostFD) @@ -981,5 +981,5 @@ func (f *fileDescription) Ioctl(ctx context.Context, uio usermem.IO, args arch.S return 0, err } - return f.FileDescriptionDefaultImpl.Ioctl(ctx, uio, args) + return f.FileDescriptionDefaultImpl.Ioctl(ctx, uio, sysno, args) } diff --git a/pkg/sentry/fsimpl/host/tty.go b/pkg/sentry/fsimpl/host/tty.go index 04ac73255..63fb30c5d 100644 --- a/pkg/sentry/fsimpl/host/tty.go +++ b/pkg/sentry/fsimpl/host/tty.go @@ -144,7 +144,7 @@ func (t *TTYFileDescription) Write(ctx context.Context, src usermem.IOSequence, } // Ioctl implements vfs.FileDescriptionImpl.Ioctl. -func (t *TTYFileDescription) Ioctl(ctx context.Context, io usermem.IO, args arch.SyscallArguments) (uintptr, error) { +func (t *TTYFileDescription) Ioctl(ctx context.Context, io usermem.IO, sysno uintptr, args arch.SyscallArguments) (uintptr, error) { task := kernel.TaskFromContext(ctx) if task == nil { return 0, linuxerr.ENOTTY @@ -299,7 +299,7 @@ func (t *TTYFileDescription) Ioctl(ctx context.Context, io usermem.IO, args arch linux.TIOCSSERIAL, linux.TIOCGPTPEER: - unimpl.EmitUnimplementedEvent(ctx) + unimpl.EmitUnimplementedEvent(ctx, sysno) fallthrough default: return 0, linuxerr.ENOTTY diff --git a/pkg/sentry/fsimpl/overlay/regular_file.go b/pkg/sentry/fsimpl/overlay/regular_file.go index 2e6f5d255..084485533 100644 --- a/pkg/sentry/fsimpl/overlay/regular_file.go +++ b/pkg/sentry/fsimpl/overlay/regular_file.go @@ -365,13 +365,13 @@ func (fd *regularFileFD) Sync(ctx context.Context) error { } // Ioctl implements vfs.FileDescriptionImpl.Ioctl. -func (fd *regularFileFD) Ioctl(ctx context.Context, uio usermem.IO, args arch.SyscallArguments) (uintptr, error) { +func (fd *regularFileFD) Ioctl(ctx context.Context, uio usermem.IO, sysno uintptr, args arch.SyscallArguments) (uintptr, error) { wrappedFD, err := fd.getCurrentFD(ctx) if err != nil { return 0, err } defer wrappedFD.DecRef(ctx) - return wrappedFD.Ioctl(ctx, uio, args) + return wrappedFD.Ioctl(ctx, uio, sysno, args) } // ConfigureMMap implements vfs.FileDescriptionImpl.ConfigureMMap. diff --git a/pkg/sentry/fsimpl/sys/kcov.go b/pkg/sentry/fsimpl/sys/kcov.go index cde68ac79..24846a0a5 100644 --- a/pkg/sentry/fsimpl/sys/kcov.go +++ b/pkg/sentry/fsimpl/sys/kcov.go @@ -75,7 +75,7 @@ type kcovFD struct { } // Ioctl implements vfs.FileDescriptionImpl.Ioctl. -func (fd *kcovFD) Ioctl(ctx context.Context, uio usermem.IO, args arch.SyscallArguments) (uintptr, error) { +func (fd *kcovFD) Ioctl(ctx context.Context, uio usermem.IO, sysno uintptr, args arch.SyscallArguments) (uintptr, error) { cmd := uint32(args[1].Int()) arg := args[2].Uint64() switch uint32(cmd) { diff --git a/pkg/sentry/kernel/pipe/pipe_util.go b/pkg/sentry/kernel/pipe/pipe_util.go index 2c3a0fff0..ebafd3959 100644 --- a/pkg/sentry/kernel/pipe/pipe_util.go +++ b/pkg/sentry/kernel/pipe/pipe_util.go @@ -135,7 +135,7 @@ func (p *Pipe) Readiness(mask waiter.EventMask) waiter.EventMask { } // Ioctl implements ioctls on the Pipe. -func (p *Pipe) Ioctl(ctx context.Context, io usermem.IO, args arch.SyscallArguments) (uintptr, error) { +func (p *Pipe) Ioctl(ctx context.Context, io usermem.IO, sysno uintptr, args arch.SyscallArguments) (uintptr, error) { // Switch on ioctl request. switch int(args[1].Int()) { case linux.FIONREAD: diff --git a/pkg/sentry/kernel/pipe/vfs.go b/pkg/sentry/kernel/pipe/vfs.go index a8320cf83..3d58249b7 100644 --- a/pkg/sentry/kernel/pipe/vfs.go +++ b/pkg/sentry/kernel/pipe/vfs.go @@ -234,8 +234,8 @@ func (fd *VFSPipeFD) Write(ctx context.Context, src usermem.IOSequence, _ vfs.Wr } // Ioctl implements vfs.FileDescriptionImpl.Ioctl. -func (fd *VFSPipeFD) Ioctl(ctx context.Context, uio usermem.IO, args arch.SyscallArguments) (uintptr, error) { - return fd.pipe.Ioctl(ctx, uio, args) +func (fd *VFSPipeFD) Ioctl(ctx context.Context, uio usermem.IO, sysno uintptr, args arch.SyscallArguments) (uintptr, error) { + return fd.pipe.Ioctl(ctx, uio, sysno, args) } // PipeSize implements fcntl(F_GETPIPE_SZ). diff --git a/pkg/sentry/socket/hostinet/socket.go b/pkg/sentry/socket/hostinet/socket.go index 806055d8e..c457cd427 100644 --- a/pkg/sentry/socket/hostinet/socket.go +++ b/pkg/sentry/socket/hostinet/socket.go @@ -162,8 +162,8 @@ func (s *Socket) Epollable() bool { } // Ioctl implements vfs.FileDescriptionImpl. -func (s *Socket) Ioctl(ctx context.Context, uio usermem.IO, args arch.SyscallArguments) (uintptr, error) { - return ioctl(ctx, s.fd, uio, args) +func (s *Socket) Ioctl(ctx context.Context, uio usermem.IO, sysno uintptr, args arch.SyscallArguments) (uintptr, error) { + return ioctl(ctx, s.fd, uio, sysno, args) } // PRead implements vfs.FileDescriptionImpl.PRead. diff --git a/pkg/sentry/socket/hostinet/socket_unsafe.go b/pkg/sentry/socket/hostinet/socket_unsafe.go index a6a03f70c..1370ca59b 100644 --- a/pkg/sentry/socket/hostinet/socket_unsafe.go +++ b/pkg/sentry/socket/hostinet/socket_unsafe.go @@ -55,7 +55,7 @@ func writev(fd int, srcs []unix.Iovec) (uint64, error) { return uint64(n), nil } -func ioctl(ctx context.Context, fd int, io usermem.IO, args arch.SyscallArguments) (uintptr, error) { +func ioctl(ctx context.Context, fd int, io usermem.IO, sysno uintptr, args arch.SyscallArguments) (uintptr, error) { switch cmd := uintptr(args[1].Int()); cmd { case unix.TIOCINQ, unix.TIOCOUTQ: var val int32 diff --git a/pkg/sentry/socket/netlink/socket.go b/pkg/sentry/socket/netlink/socket.go index 9eb5c5a3c..ef82f7c7b 100644 --- a/pkg/sentry/socket/netlink/socket.go +++ b/pkg/sentry/socket/netlink/socket.go @@ -166,7 +166,7 @@ func (s *Socket) Epollable() bool { } // Ioctl implements vfs.FileDescriptionImpl. -func (*Socket) Ioctl(context.Context, usermem.IO, arch.SyscallArguments) (uintptr, error) { +func (*Socket) Ioctl(ctx context.Context, uio usermem.IO, sysno uintptr, args arch.SyscallArguments) (uintptr, error) { // TODO(b/68878065): no ioctls supported. return 0, linuxerr.ENOTTY } diff --git a/pkg/sentry/socket/netstack/netstack.go b/pkg/sentry/socket/netstack/netstack.go index 06d1278b7..b0a3523b6 100644 --- a/pkg/sentry/socket/netstack/netstack.go +++ b/pkg/sentry/socket/netstack/netstack.go @@ -2974,7 +2974,7 @@ func (s *sock) SendMsg(t *kernel.Task, src usermem.IOSequence, to []byte, flags } // Ioctl implements vfs.FileDescriptionImpl. -func (s *sock) Ioctl(ctx context.Context, uio usermem.IO, args arch.SyscallArguments) (uintptr, error) { +func (s *sock) Ioctl(ctx context.Context, uio usermem.IO, sysno uintptr, args arch.SyscallArguments) (uintptr, error) { t := kernel.TaskFromContext(ctx) if t == nil { panic("ioctl(2) may only be called from a task goroutine") @@ -3011,11 +3011,11 @@ func (s *sock) Ioctl(ctx context.Context, uio usermem.IO, args arch.SyscallArgum return 0, err } - return Ioctl(ctx, s.Endpoint, uio, args) + return Ioctl(ctx, s.Endpoint, uio, sysno, args) } // Ioctl performs a socket ioctl. -func Ioctl(ctx context.Context, ep commonEndpoint, io usermem.IO, args arch.SyscallArguments) (uintptr, error) { +func Ioctl(ctx context.Context, ep commonEndpoint, io usermem.IO, sysno uintptr, args arch.SyscallArguments) (uintptr, error) { t := kernel.TaskFromContext(ctx) if t == nil { panic("ioctl(2) may only be called from a task goroutine") diff --git a/pkg/sentry/socket/unix/unix.go b/pkg/sentry/socket/unix/unix.go index 485ebe746..820bef6d5 100644 --- a/pkg/sentry/socket/unix/unix.go +++ b/pkg/sentry/socket/unix/unix.go @@ -271,8 +271,8 @@ func (s *Socket) Bind(t *kernel.Task, sockaddr []byte) *syserr.Error { } // Ioctl implements vfs.FileDescriptionImpl. -func (s *Socket) Ioctl(ctx context.Context, uio usermem.IO, args arch.SyscallArguments) (uintptr, error) { - return netstack.Ioctl(ctx, s.ep, uio, args) +func (s *Socket) Ioctl(ctx context.Context, uio usermem.IO, sysno uintptr, args arch.SyscallArguments) (uintptr, error) { + return netstack.Ioctl(ctx, s.ep, uio, sysno, args) } // PRead implements vfs.FileDescriptionImpl. diff --git a/pkg/sentry/syscalls/linux/sys_file.go b/pkg/sentry/syscalls/linux/sys_file.go index 292ab9e72..82ae9515c 100644 --- a/pkg/sentry/syscalls/linux/sys_file.go +++ b/pkg/sentry/syscalls/linux/sys_file.go @@ -283,7 +283,7 @@ func Ioctl(t *kernel.Task, sysno uintptr, args arch.SyscallArguments) (uintptr, return 0, nil, setAsyncOwner(t, int(fd), file, ownerType, who) } - ret, err := file.Ioctl(t, t.MemoryManager(), args) + ret, err := file.Ioctl(t, t.MemoryManager(), sysno, args) return ret, nil, err } diff --git a/pkg/sentry/unimpl/BUILD b/pkg/sentry/unimpl/BUILD index 5abc2a0a7..15945e6fe 100644 --- a/pkg/sentry/unimpl/BUILD +++ b/pkg/sentry/unimpl/BUILD @@ -1,4 +1,4 @@ -load("//tools:defs.bzl", "go_library", "proto_library") +load("//tools:defs.bzl", "go_library", "go_test", "proto_library") package( default_applicable_licenses = ["//:license"], @@ -21,3 +21,12 @@ go_library( "//pkg/log", ], ) + +go_test( + name = "events_test", + srcs = ["events_test.go"], + deps = [ + ":unimpl", + "//pkg/sentry/kernel", + ], +) diff --git a/pkg/sentry/unimpl/events.go b/pkg/sentry/unimpl/events.go index 73ed9372f..4b79e4e98 100644 --- a/pkg/sentry/unimpl/events.go +++ b/pkg/sentry/unimpl/events.go @@ -31,15 +31,15 @@ const ( // Events interface defines method to emit unsupported events. type Events interface { - EmitUnimplementedEvent(context.Context) + EmitUnimplementedEvent(ctx context.Context, sysno uintptr) } // EmitUnimplementedEvent emits unsupported syscall event to the context. -func EmitUnimplementedEvent(ctx context.Context) { +func EmitUnimplementedEvent(ctx context.Context, sysno uintptr) { e := ctx.Value(CtxEvents) if e == nil { log.Warningf("Context.Value(CtxEvents) not present, unimplemented syscall event not reported.") return } - e.(Events).EmitUnimplementedEvent(ctx) + e.(Events).EmitUnimplementedEvent(ctx, sysno) } diff --git a/pkg/sentry/unimpl/events_test.go b/pkg/sentry/unimpl/events_test.go new file mode 100644 index 000000000..91b6e89dc --- /dev/null +++ b/pkg/sentry/unimpl/events_test.go @@ -0,0 +1,28 @@ +// Copyright 2023 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 events_test verifies that kernel.Kernel implements interface unimpl.Events. +package events_test + +import ( + "testing" + + "gvisor.dev/gvisor/pkg/sentry/kernel" + "gvisor.dev/gvisor/pkg/sentry/unimpl" +) + +// TestInterfaceMatch verifies that kernel.Kernel implements interface unimpl.Events. +func TestInterfaceMatch(t *testing.T) { + var _ = (unimpl.Events)((*kernel.Kernel)(nil)) +} diff --git a/pkg/sentry/vfs/file_description.go b/pkg/sentry/vfs/file_description.go index a8c00e372..fb6a3cc75 100644 --- a/pkg/sentry/vfs/file_description.go +++ b/pkg/sentry/vfs/file_description.go @@ -446,7 +446,7 @@ type FileDescriptionImpl interface { ConfigureMMap(ctx context.Context, opts *memmap.MMapOpts) error // Ioctl implements the ioctl(2) syscall. - Ioctl(ctx context.Context, uio usermem.IO, args arch.SyscallArguments) (uintptr, error) + Ioctl(ctx context.Context, uio usermem.IO, sysno uintptr, args arch.SyscallArguments) (uintptr, error) // ListXattr returns all extended attribute names for the file. ListXattr(ctx context.Context, size uint64) ([]string, error) @@ -708,8 +708,8 @@ func (fd *FileDescription) ConfigureMMap(ctx context.Context, opts *memmap.MMapO } // Ioctl implements the ioctl(2) syscall. -func (fd *FileDescription) Ioctl(ctx context.Context, uio usermem.IO, args arch.SyscallArguments) (uintptr, error) { - return fd.impl.Ioctl(ctx, uio, args) +func (fd *FileDescription) Ioctl(ctx context.Context, uio usermem.IO, sysno uintptr, args arch.SyscallArguments) (uintptr, error) { + return fd.impl.Ioctl(ctx, uio, sysno, args) } // ListXattr returns all extended attribute names for the file represented by diff --git a/pkg/sentry/vfs/file_description_impl_util.go b/pkg/sentry/vfs/file_description_impl_util.go index b47d0c1b9..499d9fed3 100644 --- a/pkg/sentry/vfs/file_description_impl_util.go +++ b/pkg/sentry/vfs/file_description_impl_util.go @@ -143,7 +143,7 @@ func (FileDescriptionDefaultImpl) ConfigureMMap(ctx context.Context, opts *memma // Ioctl implements FileDescriptionImpl.Ioctl analogously to // file_operations::unlocked_ioctl == NULL in Linux. -func (FileDescriptionDefaultImpl) Ioctl(ctx context.Context, uio usermem.IO, args arch.SyscallArguments) (uintptr, error) { +func (FileDescriptionDefaultImpl) Ioctl(ctx context.Context, uio usermem.IO, sysno uintptr, args arch.SyscallArguments) (uintptr, error) { return 0, linuxerr.ENOTTY } diff --git a/pkg/sentry/vfs/inotify.go b/pkg/sentry/vfs/inotify.go index aea54a5d5..85f018ccf 100644 --- a/pkg/sentry/vfs/inotify.go +++ b/pkg/sentry/vfs/inotify.go @@ -253,7 +253,7 @@ func (i *Inotify) Read(ctx context.Context, dst usermem.IOSequence, opts ReadOpt } // Ioctl implements FileDescriptionImpl.Ioctl. -func (i *Inotify) Ioctl(ctx context.Context, uio usermem.IO, args arch.SyscallArguments) (uintptr, error) { +func (i *Inotify) Ioctl(ctx context.Context, uio usermem.IO, sysno uintptr, args arch.SyscallArguments) (uintptr, error) { switch args[1].Int() { case linux.FIONREAD: i.evMu.Lock() diff --git a/pkg/sentry/vfs/opath.go b/pkg/sentry/vfs/opath.go index df51bb227..ec8084915 100644 --- a/pkg/sentry/vfs/opath.go +++ b/pkg/sentry/vfs/opath.go @@ -64,7 +64,7 @@ func (fd *opathFD) Write(ctx context.Context, src usermem.IOSequence, opts Write } // Ioctl implements FileDescriptionImpl.Ioctl. -func (fd *opathFD) Ioctl(ctx context.Context, uio usermem.IO, args arch.SyscallArguments) (uintptr, error) { +func (fd *opathFD) Ioctl(ctx context.Context, uio usermem.IO, sysno uintptr, args arch.SyscallArguments) (uintptr, error) { return 0, linuxerr.EBADF }