diff options
Diffstat (limited to 'pkg/sentry/kernel')
52 files changed, 158 insertions, 176 deletions
diff --git a/pkg/sentry/kernel/BUILD b/pkg/sentry/kernel/BUILD index c4a7dacb2..0ebacefa6 100644 --- a/pkg/sentry/kernel/BUILD +++ b/pkg/sentry/kernel/BUILD @@ -1,58 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "kernel_state", - srcs = [ - "abstract_socket_namespace.go", - "fd_map.go", - "fs_context.go", - "ipc_namespace.go", - "kernel.go", - "kernel_state.go", - "pending_signals.go", - "pending_signals_state.go", - "process_group_list.go", - "ptrace.go", - "rseq.go", - "session_list.go", - "sessions.go", - "signal.go", - "signal_handlers.go", - "syscalls.go", - "syscalls_state.go", - "syslog.go", - "task.go", - "task_clone.go", - "task_context.go", - "task_exec.go", - "task_exit.go", - "task_list.go", - "task_resources.go", - "task_run.go", - "task_sched.go", - "task_signals.go", - "task_start.go", - "task_syscall.go", - "thread_group.go", - "threads.go", - "timekeeper.go", - "timekeeper_state.go", - "timer.go", - "uts_namespace.go", - "vdso.go", - "version.go", - ], - out = "kernel_autogen_state.go", - imports = [ - "gvisor.googlesource.com/gvisor/pkg/sentry/arch", - "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/kdefs", - "gvisor.googlesource.com/gvisor/pkg/tcpip", - ], - package = "kernel", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_template_instance( name = "pending_signals_list", @@ -118,7 +67,6 @@ go_library( "fs_context.go", "ipc_namespace.go", "kernel.go", - "kernel_autogen_state.go", "kernel_state.go", "pending_signals.go", "pending_signals_list.go", @@ -164,6 +112,11 @@ go_library( "version.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel", + imports = [ + "gvisor.googlesource.com/gvisor/pkg/sentry/arch", + # "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/kdefs", + "gvisor.googlesource.com/gvisor/pkg/tcpip", + ], visibility = ["//:sandbox"], deps = [ "//pkg/abi", diff --git a/pkg/sentry/kernel/abstract_socket_namespace.go b/pkg/sentry/kernel/abstract_socket_namespace.go index 014c4a3bf..d6d1d341d 100644 --- a/pkg/sentry/kernel/abstract_socket_namespace.go +++ b/pkg/sentry/kernel/abstract_socket_namespace.go @@ -22,6 +22,7 @@ import ( "gvisor.googlesource.com/gvisor/pkg/tcpip/transport/unix" ) +// +stateify savable type abstractEndpoint struct { ep unix.BoundEndpoint wr *refs.WeakRef @@ -39,6 +40,8 @@ func (e *abstractEndpoint) WeakRefGone() { } // AbstractSocketNamespace is used to implement the Linux abstract socket functionality. +// +// +stateify savable type AbstractSocketNamespace struct { mu sync.Mutex `state:"nosave"` diff --git a/pkg/sentry/kernel/auth/BUILD b/pkg/sentry/kernel/auth/BUILD index 5b7b30557..a81085372 100644 --- a/pkg/sentry/kernel/auth/BUILD +++ b/pkg/sentry/kernel/auth/BUILD @@ -1,20 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "auth_state", - srcs = [ - "credentials.go", - "id.go", - "id_map_range.go", - "id_map_set.go", - "user_namespace.go", - ], - out = "auth_state.go", - package = "auth", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_template_instance( name = "id_map_range", @@ -48,7 +35,6 @@ go_library( name = "auth", srcs = [ "auth.go", - "auth_state.go", "capability_set.go", "context.go", "credentials.go", @@ -66,7 +52,6 @@ go_library( "//pkg/bits", "//pkg/log", "//pkg/sentry/context", - "//pkg/state", "//pkg/syserror", ], ) diff --git a/pkg/sentry/kernel/auth/credentials.go b/pkg/sentry/kernel/auth/credentials.go index f6fb05285..f18f7dac9 100644 --- a/pkg/sentry/kernel/auth/credentials.go +++ b/pkg/sentry/kernel/auth/credentials.go @@ -21,6 +21,8 @@ import ( // Credentials contains information required to authorize privileged operations // in a user namespace. +// +// +stateify savable type Credentials struct { // Real/effective/saved user/group IDs in the root user namespace. None of // these should ever be NoID. diff --git a/pkg/sentry/kernel/auth/id_map.go b/pkg/sentry/kernel/auth/id_map.go index 6adb33530..bd0090e0f 100644 --- a/pkg/sentry/kernel/auth/id_map.go +++ b/pkg/sentry/kernel/auth/id_map.go @@ -77,6 +77,8 @@ func (ns *UserNamespace) allIDsMapped(m *idMapSet, start, end uint32) bool { // An IDMapEntry represents a mapping from a range of contiguous IDs in a user // namespace to an equally-sized range of contiguous IDs in the namespace's // parent. +// +// +stateify savable type IDMapEntry struct { // FirstID is the first ID in the range in the namespace. FirstID uint32 diff --git a/pkg/sentry/kernel/auth/user_namespace.go b/pkg/sentry/kernel/auth/user_namespace.go index 0980aeadf..d359f3f31 100644 --- a/pkg/sentry/kernel/auth/user_namespace.go +++ b/pkg/sentry/kernel/auth/user_namespace.go @@ -23,6 +23,8 @@ import ( // A UserNamespace represents a user namespace. See user_namespaces(7) for // details. +// +// +stateify savable type UserNamespace struct { // parent is this namespace's parent. If this is the root namespace, parent // is nil. The parent pointer is immutable. diff --git a/pkg/sentry/kernel/epoll/BUILD b/pkg/sentry/kernel/epoll/BUILD index 7d491efbc..5e8b36ed6 100644 --- a/pkg/sentry/kernel/epoll/BUILD +++ b/pkg/sentry/kernel/epoll/BUILD @@ -1,22 +1,11 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "epoll_autogen_state", - srcs = [ - "epoll.go", - "epoll_state.go", - ], - out = "epoll_autogen_state.go", - package = "epoll", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "epoll", srcs = [ "epoll.go", - "epoll_autogen_state.go", "epoll_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/epoll", @@ -29,9 +18,7 @@ go_library( "//pkg/sentry/fs/anon", "//pkg/sentry/fs/fsutil", "//pkg/sentry/kernel/kdefs", - "//pkg/sentry/kernel/time", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/waiter", ], ) diff --git a/pkg/sentry/kernel/epoll/epoll.go b/pkg/sentry/kernel/epoll/epoll.go index b572fcd7e..d87e64a1c 100644 --- a/pkg/sentry/kernel/epoll/epoll.go +++ b/pkg/sentry/kernel/epoll/epoll.go @@ -58,6 +58,8 @@ const ( // potentially be reassigned. We also cannot use just the file pointer because // it is possible to have multiple entries for the same file object as long as // they are created with different FDs (i.e., the FDs point to the same file). +// +// +stateify savable type FileIdentifier struct { File *fs.File Fd kdefs.FD @@ -65,6 +67,8 @@ type FileIdentifier struct { // pollEntry holds all the state associated with an event poll entry, that is, // a file being observed by an event poll object. +// +// +stateify savable type pollEntry struct { ilist.Entry file *refs.WeakRef `state:"manual"` @@ -92,6 +96,8 @@ func (p *pollEntry) WeakRefGone() { // EventPoll holds all the state associated with an event poll object, that is, // collection of files to observe and their current state. +// +// +stateify savable type EventPoll struct { fsutil.PipeSeek `state:"zerovalue"` fsutil.NotDirReaddir `state:"zerovalue"` @@ -102,7 +108,7 @@ type EventPoll struct { // Wait queue is used to notify interested parties when the event poll // object itself becomes readable or writable. - waiter.Queue + waiter.Queue `state:"zerovalue"` // files is the map of all the files currently being observed, it is // protected by mu. diff --git a/pkg/sentry/kernel/eventfd/BUILD b/pkg/sentry/kernel/eventfd/BUILD index 7ec179bd8..cc1120b4f 100644 --- a/pkg/sentry/kernel/eventfd/BUILD +++ b/pkg/sentry/kernel/eventfd/BUILD @@ -1,33 +1,19 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "eventfd_state", - srcs = [ - "eventfd.go", - ], - out = "eventfd_state.go", - package = "eventfd", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "eventfd", - srcs = [ - "eventfd.go", - "eventfd_state.go", - ], + srcs = ["eventfd.go"], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/eventfd", visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", - "//pkg/refs", "//pkg/sentry/context", "//pkg/sentry/fs", "//pkg/sentry/fs/anon", "//pkg/sentry/fs/fsutil", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", "//pkg/waiter", "//pkg/waiter/fdnotifier", diff --git a/pkg/sentry/kernel/eventfd/eventfd.go b/pkg/sentry/kernel/eventfd/eventfd.go index bd50bd9fe..a4ada0e78 100644 --- a/pkg/sentry/kernel/eventfd/eventfd.go +++ b/pkg/sentry/kernel/eventfd/eventfd.go @@ -35,6 +35,8 @@ import ( // EventOperations represents an event with the semantics of Linux's file-based event // notification (eventfd). Eventfds are usually internal to the Sentry but in certain // situations they may be converted into a host-backed eventfd. +// +// +stateify savable type EventOperations struct { fsutil.NoopRelease `state:"nosave"` fsutil.PipeSeek `state:"nosave"` @@ -49,7 +51,7 @@ type EventOperations struct { // Queue is used to notify interested parties when the event object // becomes readable or writable. - wq waiter.Queue `state:"nosave"` + wq waiter.Queue `state:"zerovalue"` // val is the current value of the event counter. val uint64 diff --git a/pkg/sentry/kernel/fd_map.go b/pkg/sentry/kernel/fd_map.go index 299506330..d5d4aaacb 100644 --- a/pkg/sentry/kernel/fd_map.go +++ b/pkg/sentry/kernel/fd_map.go @@ -46,6 +46,8 @@ func (f FDs) Less(i, j int) bool { } // FDFlags define flags for an individual descriptor. +// +// +stateify savable type FDFlags struct { // CloseOnExec indicates the descriptor should be closed on exec. CloseOnExec bool @@ -69,12 +71,16 @@ func (f FDFlags) ToLinuxFDFlags() (mask uint) { // descriptor holds the details about a file descriptor, namely a pointer the // file itself and the descriptor flags. +// +// +stateify savable type descriptor struct { file *fs.File flags FDFlags } // FDMap is used to manage File references and flags. +// +// +stateify savable type FDMap struct { refs.AtomicRefCount k *Kernel diff --git a/pkg/sentry/kernel/fs_context.go b/pkg/sentry/kernel/fs_context.go index dbc097696..f3f05e8f5 100644 --- a/pkg/sentry/kernel/fs_context.go +++ b/pkg/sentry/kernel/fs_context.go @@ -25,6 +25,8 @@ import ( // FSContext contains filesystem context. // // This includes umask and working directory. +// +// +stateify savable type FSContext struct { refs.AtomicRefCount diff --git a/pkg/sentry/kernel/futex/BUILD b/pkg/sentry/kernel/futex/BUILD index a97a43549..b44a26974 100644 --- a/pkg/sentry/kernel/futex/BUILD +++ b/pkg/sentry/kernel/futex/BUILD @@ -1,7 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_template_instance( name = "waiter_list", @@ -14,29 +14,15 @@ go_template_instance( }, ) -go_stateify( - name = "futex_state", - srcs = [ - "futex.go", - "waiter_list.go", - ], - out = "futex_state.go", - package = "futex", -) - go_library( name = "futex", srcs = [ "futex.go", - "futex_state.go", "waiter_list.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/futex", visibility = ["//pkg/sentry:internal"], - deps = [ - "//pkg/state", - "//pkg/syserror", - ], + deps = ["//pkg/syserror"], ) go_test( diff --git a/pkg/sentry/kernel/futex/futex.go b/pkg/sentry/kernel/futex/futex.go index 15e3e5e2c..4a1f2a0ef 100644 --- a/pkg/sentry/kernel/futex/futex.go +++ b/pkg/sentry/kernel/futex/futex.go @@ -196,6 +196,8 @@ func bucketIndexForAddr(addr uintptr) uintptr { } // Manager holds futex state for a single virtual address space. +// +// +stateify savable type Manager struct { buckets [bucketCount]bucket `state:"zerovalue"` } diff --git a/pkg/sentry/kernel/ipc_namespace.go b/pkg/sentry/kernel/ipc_namespace.go index a86bda77b..5eef49f59 100644 --- a/pkg/sentry/kernel/ipc_namespace.go +++ b/pkg/sentry/kernel/ipc_namespace.go @@ -21,6 +21,8 @@ import ( ) // IPCNamespace represents an IPC namespace. +// +// +stateify savable type IPCNamespace struct { // User namespace which owns this IPC namespace. Immutable. userNS *auth.UserNamespace diff --git a/pkg/sentry/kernel/kernel.go b/pkg/sentry/kernel/kernel.go index 64439cd9d..419a1d473 100644 --- a/pkg/sentry/kernel/kernel.go +++ b/pkg/sentry/kernel/kernel.go @@ -62,6 +62,8 @@ import ( // Kernel represents an emulated Linux kernel. It must be initialized by calling // Init() or LoadFrom(). +// +// +stateify savable type Kernel struct { // extMu serializes external changes to the Kernel with calls to // Kernel.SaveTo. (Kernel.SaveTo requires that the state of the Kernel @@ -158,7 +160,7 @@ type Kernel struct { // exitErr is the error causing the sandbox to exit, if any. It is // protected by extMu. - exitErr error + exitErr error `state:"nosave"` // danglingEndpoints is used to save / restore tcpip.DanglingEndpoints. danglingEndpoints struct{} `state:".([]tcpip.Endpoint)"` diff --git a/pkg/sentry/kernel/pending_signals.go b/pkg/sentry/kernel/pending_signals.go index 5dc0f266c..06be5a7e1 100644 --- a/pkg/sentry/kernel/pending_signals.go +++ b/pkg/sentry/kernel/pending_signals.go @@ -38,6 +38,8 @@ const ( // pendingSignals holds a collection of pending signals. The zero value of // pendingSignals is a valid empty collection. pendingSignals is thread-unsafe; // users must provide synchronization. +// +// +stateify savable type pendingSignals struct { // signals contains all pending signals. // @@ -52,11 +54,14 @@ type pendingSignals struct { } // pendingSignalQueue holds a pendingSignalList for a single signal number. +// +// +stateify savable type pendingSignalQueue struct { pendingSignalList length int } +// +stateify savable type pendingSignal struct { // pendingSignalEntry links into a pendingSignalList. pendingSignalEntry diff --git a/pkg/sentry/kernel/pipe/BUILD b/pkg/sentry/kernel/pipe/BUILD index 4600d19bd..19b23c6d2 100644 --- a/pkg/sentry/kernel/pipe/BUILD +++ b/pkg/sentry/kernel/pipe/BUILD @@ -1,20 +1,6 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") - -go_stateify( - name = "pipe_state", - srcs = [ - "buffers.go", - "node.go", - "pipe.go", - "reader.go", - "reader_writer.go", - "writer.go", - ], - out = "pipe_state.go", - package = "pipe", -) +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_library( name = "pipe", @@ -23,7 +9,6 @@ go_library( "device.go", "node.go", "pipe.go", - "pipe_state.go", "reader.go", "reader_writer.go", "writer.go", @@ -34,15 +19,12 @@ go_library( "//pkg/abi/linux", "//pkg/amutex", "//pkg/ilist", - "//pkg/log", - "//pkg/refs", "//pkg/sentry/arch", "//pkg/sentry/context", "//pkg/sentry/device", "//pkg/sentry/fs", "//pkg/sentry/fs/fsutil", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", "//pkg/waiter", ], diff --git a/pkg/sentry/kernel/pipe/buffers.go b/pkg/sentry/kernel/pipe/buffers.go index f300537c5..a82e45c3f 100644 --- a/pkg/sentry/kernel/pipe/buffers.go +++ b/pkg/sentry/kernel/pipe/buffers.go @@ -20,6 +20,8 @@ import ( // Buffer encapsulates a queueable byte buffer that can // easily be truncated. It is designed only for use with pipes. +// +// +stateify savable type Buffer struct { ilist.Entry data []byte diff --git a/pkg/sentry/kernel/pipe/node.go b/pkg/sentry/kernel/pipe/node.go index e418cf174..23d692da1 100644 --- a/pkg/sentry/kernel/pipe/node.go +++ b/pkg/sentry/kernel/pipe/node.go @@ -24,6 +24,8 @@ import ( ) // inodeOperations wraps fs.InodeOperations operations with common pipe opening semantics. +// +// +stateify savable type inodeOperations struct { fs.InodeOperations diff --git a/pkg/sentry/kernel/pipe/pipe.go b/pkg/sentry/kernel/pipe/pipe.go index 9a21df5b4..ced2559a7 100644 --- a/pkg/sentry/kernel/pipe/pipe.go +++ b/pkg/sentry/kernel/pipe/pipe.go @@ -41,6 +41,8 @@ const DefaultPipeSize = 65536 // Pipe is an encapsulation of a platform-independent pipe. // It manages a buffered byte queue shared between a reader/writer // pair. +// +// +stateify savable type Pipe struct { waiter.Queue `state:"nosave"` diff --git a/pkg/sentry/kernel/pipe/reader.go b/pkg/sentry/kernel/pipe/reader.go index 40d5e4943..1fa5e9a32 100644 --- a/pkg/sentry/kernel/pipe/reader.go +++ b/pkg/sentry/kernel/pipe/reader.go @@ -20,6 +20,8 @@ import ( // Reader satisfies the fs.FileOperations interface for read-only pipes. // Reader should be used with !fs.FileFlags.Write to reject writes. +// +// +stateify savable type Reader struct { ReaderWriter } diff --git a/pkg/sentry/kernel/pipe/reader_writer.go b/pkg/sentry/kernel/pipe/reader_writer.go index dc642a3a6..82607367b 100644 --- a/pkg/sentry/kernel/pipe/reader_writer.go +++ b/pkg/sentry/kernel/pipe/reader_writer.go @@ -31,6 +31,8 @@ import ( // read and write requests. This should only be used directly for named pipes. // pipe(2) and pipe2(2) only support unidirectional pipes and should use // either pipe.Reader or pipe.Writer. +// +// +stateify savable type ReaderWriter struct { fsutil.PipeSeek `state:"nosave"` fsutil.NotDirReaddir `state:"nosave"` diff --git a/pkg/sentry/kernel/pipe/writer.go b/pkg/sentry/kernel/pipe/writer.go index fd13008ac..d93324b53 100644 --- a/pkg/sentry/kernel/pipe/writer.go +++ b/pkg/sentry/kernel/pipe/writer.go @@ -20,6 +20,8 @@ import ( // Writer satisfies the fs.FileOperations interface for write-only pipes. // Writer should be used with !fs.FileFlags.Read to reject reads. +// +// +stateify savable type Writer struct { ReaderWriter } diff --git a/pkg/sentry/kernel/ptrace.go b/pkg/sentry/kernel/ptrace.go index f1c2c4bf0..e9e69004d 100644 --- a/pkg/sentry/kernel/ptrace.go +++ b/pkg/sentry/kernel/ptrace.go @@ -25,6 +25,8 @@ import ( // ptraceOptions are the subset of options controlling a task's ptrace behavior // that are set by ptrace(PTRACE_SETOPTIONS). +// +// +stateify savable type ptraceOptions struct { // ExitKill is true if the tracee should be sent SIGKILL when the tracer // exits. @@ -185,6 +187,8 @@ func (t *Task) hasTracer() bool { } // ptraceStop is a TaskStop placed on tasks in a ptrace-stop. +// +// +stateify savable type ptraceStop struct { // If frozen is true, the stopped task's tracer is currently operating on // it, so Task.Kill should not remove the stop. diff --git a/pkg/sentry/kernel/rseq.go b/pkg/sentry/kernel/rseq.go index 635372993..1f3de58e3 100644 --- a/pkg/sentry/kernel/rseq.go +++ b/pkg/sentry/kernel/rseq.go @@ -23,6 +23,8 @@ import ( // Restartable sequences, as described in https://lwn.net/Articles/650333/. // RSEQCriticalRegion describes a restartable sequence critical region. +// +// +stateify savable type RSEQCriticalRegion struct { // When a task in this thread group has its CPU preempted (as defined by // platform.ErrContextCPUPreempted) or has a signal delivered to an diff --git a/pkg/sentry/kernel/semaphore/BUILD b/pkg/sentry/kernel/semaphore/BUILD index 969145fe1..e7fa44e2c 100644 --- a/pkg/sentry/kernel/semaphore/BUILD +++ b/pkg/sentry/kernel/semaphore/BUILD @@ -1,7 +1,7 @@ package(licenses = ["notice"]) # Apache 2.0 load("//tools/go_generics:defs.bzl", "go_template_instance") -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test") +load("//tools/go_stateify:defs.bzl", "go_library", "go_test") go_template_instance( name = "waiter_list", @@ -14,21 +14,10 @@ go_template_instance( }, ) -go_stateify( - name = "semaphore_state", - srcs = [ - "semaphore.go", - "waiter_list.go", - ], - out = "semaphore_autogen_state.go", - package = "semaphore", -) - go_library( name = "semaphore", srcs = [ "semaphore.go", - "semaphore_autogen_state.go", "waiter_list.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/semaphore", @@ -40,8 +29,6 @@ go_library( "//pkg/sentry/fs", "//pkg/sentry/kernel/auth", "//pkg/sentry/kernel/time", - "//pkg/state", - "//pkg/state/statefile", "//pkg/syserror", ], ) diff --git a/pkg/sentry/kernel/semaphore/semaphore.go b/pkg/sentry/kernel/semaphore/semaphore.go index a1ee83ce5..aa07946cf 100644 --- a/pkg/sentry/kernel/semaphore/semaphore.go +++ b/pkg/sentry/kernel/semaphore/semaphore.go @@ -42,6 +42,8 @@ const ( ) // Registry maintains a set of semaphores that can be found by key or ID. +// +// +stateify savable type Registry struct { // userNS owning the ipc name this registry belongs to. Immutable. userNS *auth.UserNamespace @@ -52,6 +54,8 @@ type Registry struct { } // Set represents a set of semaphores that can be operated atomically. +// +// +stateify savable type Set struct { // registry owning this sem set. Immutable. registry *Registry @@ -79,6 +83,8 @@ type Set struct { } // sem represents a single semanphore from a set. +// +// +stateify savable type sem struct { value int16 waiters waiterList `state:"zerovalue"` @@ -86,6 +92,8 @@ type sem struct { // waiter represents a caller that is waiting for the semaphore value to // become positive or zero. +// +// +stateify savable type waiter struct { waiterEntry diff --git a/pkg/sentry/kernel/sessions.go b/pkg/sentry/kernel/sessions.go index fa4c7b8f6..cf4e18805 100644 --- a/pkg/sentry/kernel/sessions.go +++ b/pkg/sentry/kernel/sessions.go @@ -27,6 +27,8 @@ type SessionID ThreadID type ProcessGroupID ThreadID // Session contains a leader threadgroup and a list of ProcessGroups. +// +// +stateify savable type Session struct { refs refs.AtomicRefCount @@ -76,6 +78,8 @@ func (s *Session) decRef() { } // ProcessGroup contains an originator threadgroup and a parent Session. +// +// +stateify savable type ProcessGroup struct { refs refs.AtomicRefCount // not exported. diff --git a/pkg/sentry/kernel/shm/BUILD b/pkg/sentry/kernel/shm/BUILD index 0f88eb0ac..40e641355 100644 --- a/pkg/sentry/kernel/shm/BUILD +++ b/pkg/sentry/kernel/shm/BUILD @@ -1,22 +1,12 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "shm_state", - srcs = [ - "shm.go", - ], - out = "shm_autogen_state.go", - package = "shm", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "shm", srcs = [ "device.go", "shm.go", - "shm_autogen_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/shm", visibility = ["//pkg/sentry:internal"], @@ -33,7 +23,6 @@ go_library( "//pkg/sentry/platform", "//pkg/sentry/usage", "//pkg/sentry/usermem", - "//pkg/state", "//pkg/syserror", ], ) diff --git a/pkg/sentry/kernel/shm/shm.go b/pkg/sentry/kernel/shm/shm.go index 7217e8103..1ac444094 100644 --- a/pkg/sentry/kernel/shm/shm.go +++ b/pkg/sentry/kernel/shm/shm.go @@ -72,6 +72,8 @@ const ( // Registry tracks all shared memory segments in an IPC namespace. The registry // provides the mechanisms for creating and finding segments, and reporting // global shm parameters. +// +// +stateify savable type Registry struct { // userNS owns the IPC namespace this registry belong to. Immutable. userNS *auth.UserNamespace @@ -288,6 +290,8 @@ func (r *Registry) remove(s *Shm) { // shmctl(SHM_RMID). // // Shm implements memmap.Mappable and memmap.MappingIdentity. +// +// +stateify savable type Shm struct { // AtomicRefCount tracks the number of references to this segment from // maps. A segment always holds a reference to itself, until it's marked for diff --git a/pkg/sentry/kernel/signal_handlers.go b/pkg/sentry/kernel/signal_handlers.go index 21ba4ee70..3649f5e4d 100644 --- a/pkg/sentry/kernel/signal_handlers.go +++ b/pkg/sentry/kernel/signal_handlers.go @@ -22,6 +22,8 @@ import ( ) // SignalHandlers holds information about signal actions. +// +// +stateify savable type SignalHandlers struct { // mu protects actions, as well as the signal state of all tasks and thread // groups using this SignalHandlers object. (See comment on diff --git a/pkg/sentry/kernel/syscalls.go b/pkg/sentry/kernel/syscalls.go index e20fa3eb6..4c7811b6c 100644 --- a/pkg/sentry/kernel/syscalls.go +++ b/pkg/sentry/kernel/syscalls.go @@ -176,6 +176,8 @@ type Stracer interface { // SyscallTable is a lookup table of system calls. Critically, a SyscallTable // is *immutable*. In order to make supporting suspend and resume sane, they // must be uniquely registered and may not change during operation. +// +// +stateify savable type SyscallTable struct { // OS is the operating system that this syscall table implements. OS abi.OS `state:"wait"` diff --git a/pkg/sentry/kernel/syslog.go b/pkg/sentry/kernel/syslog.go index 31541749e..125312b6a 100644 --- a/pkg/sentry/kernel/syslog.go +++ b/pkg/sentry/kernel/syslog.go @@ -23,6 +23,8 @@ import ( // syslog represents a sentry-global kernel log. // // Currently, it contains only fun messages for a dmesg easter egg. +// +// +stateify savable type syslog struct { // mu protects the below. mu sync.Mutex `state:"nosave"` diff --git a/pkg/sentry/kernel/task.go b/pkg/sentry/kernel/task.go index 7f6735320..ae9b3d175 100644 --- a/pkg/sentry/kernel/task.go +++ b/pkg/sentry/kernel/task.go @@ -52,6 +52,8 @@ import ( // All fields that are "exclusive to the task goroutine" can only be accessed // by the task goroutine while it is running. The task goroutine does not // require synchronization to read or write these fields. +// +// +stateify savable type Task struct { taskNode diff --git a/pkg/sentry/kernel/task_clone.go b/pkg/sentry/kernel/task_clone.go index a61283267..38f7826e2 100644 --- a/pkg/sentry/kernel/task_clone.go +++ b/pkg/sentry/kernel/task_clone.go @@ -349,6 +349,7 @@ func (t *Task) unstopVforkParent() { } } +// +stateify savable type runSyscallAfterPtraceEventClone struct { vforkChild *Task @@ -366,6 +367,7 @@ func (r *runSyscallAfterPtraceEventClone) execute(t *Task) taskRunState { return (*runSyscallExit)(nil) } +// +stateify savable type runSyscallAfterVforkStop struct { // childTID has the same meaning as // runSyscallAfterPtraceEventClone.vforkChildTID. @@ -471,6 +473,8 @@ func (t *Task) Unshare(opts *SharingOptions) error { // current MM. (Normally, CLONE_VFORK is used in conjunction with CLONE_VM, so // that the child and parent share mappings until the child execve()s into a // new process image or exits.) +// +// +stateify savable type vforkStop struct{} // StopIgnoresKill implements TaskStop.Killable. diff --git a/pkg/sentry/kernel/task_context.go b/pkg/sentry/kernel/task_context.go index 5c563ba08..9a59cbd33 100644 --- a/pkg/sentry/kernel/task_context.go +++ b/pkg/sentry/kernel/task_context.go @@ -35,6 +35,8 @@ var ErrNoSyscalls = errors.New("no syscall table found") type Auxmap map[string]interface{} // TaskContext is the subset of a task's data that is provided by the loader. +// +// +stateify savable type TaskContext struct { // Name is the thread name set by the prctl(PR_SET_NAME) system call. Name string diff --git a/pkg/sentry/kernel/task_exec.go b/pkg/sentry/kernel/task_exec.go index 2285847a2..385299b24 100644 --- a/pkg/sentry/kernel/task_exec.go +++ b/pkg/sentry/kernel/task_exec.go @@ -73,6 +73,8 @@ import ( // execStop is a TaskStop that a task sets on itself when it wants to execve // and is waiting for the other tasks in its thread group to exit first. +// +// +stateify savable type execStop struct{} // Killable implements TaskStop.Killable. @@ -119,6 +121,8 @@ func (t *Task) Execve(newTC *TaskContext) (*SyscallControl, error) { // The runSyscallAfterExecStop state continues execve(2) after all siblings of // a thread in the execve syscall have exited. +// +// +stateify savable type runSyscallAfterExecStop struct { tc *TaskContext } diff --git a/pkg/sentry/kernel/task_exit.go b/pkg/sentry/kernel/task_exit.go index d6604f37b..b16844e91 100644 --- a/pkg/sentry/kernel/task_exit.go +++ b/pkg/sentry/kernel/task_exit.go @@ -38,6 +38,8 @@ import ( // An ExitStatus is a value communicated from an exiting task or thread group // to the party that reaps it. +// +// +stateify savable type ExitStatus struct { // Code is the numeric value passed to the call to exit or exit_group that // caused the exit. If the exit was not caused by such a call, Code is 0. @@ -222,6 +224,8 @@ func (t *Task) advanceExitStateLocked(oldExit, newExit TaskExitState) { } // runExit is the entry point into the task exit path. +// +// +stateify savable type runExit struct{} func (*runExit) execute(t *Task) taskRunState { @@ -229,6 +233,7 @@ func (*runExit) execute(t *Task) taskRunState { return (*runExitMain)(nil) } +// +stateify savable type runExitMain struct{} func (*runExitMain) execute(t *Task) taskRunState { @@ -531,6 +536,7 @@ func (t *Task) reparentLocked(parent *Task) { // tracer (if one exists) and reaps the leader immediately. In Linux, this is // in fs/exec.c:de_thread(); in the sentry, this is in Task.promoteLocked(). +// +stateify savable type runExitNotify struct{} func (*runExitNotify) execute(t *Task) taskRunState { diff --git a/pkg/sentry/kernel/task_resources.go b/pkg/sentry/kernel/task_resources.go index 4ca25664a..0832bf989 100644 --- a/pkg/sentry/kernel/task_resources.go +++ b/pkg/sentry/kernel/task_resources.go @@ -21,6 +21,8 @@ import ( // TaskResources is the subset of a task's data provided by its creator that is // not provided by the loader. +// +// +stateify savable type TaskResources struct { // SignalMask is the set of signals whose delivery is currently blocked. // diff --git a/pkg/sentry/kernel/task_run.go b/pkg/sentry/kernel/task_run.go index a03fa6ac0..8dd0ef6ea 100644 --- a/pkg/sentry/kernel/task_run.go +++ b/pkg/sentry/kernel/task_run.go @@ -131,6 +131,8 @@ func (t *Task) doStop() { // The runApp state checks for interrupts before executing untrusted // application code. +// +// +stateify savable type runApp struct{} func (*runApp) execute(t *Task) taskRunState { diff --git a/pkg/sentry/kernel/task_sched.go b/pkg/sentry/kernel/task_sched.go index b50139077..49141ab74 100644 --- a/pkg/sentry/kernel/task_sched.go +++ b/pkg/sentry/kernel/task_sched.go @@ -65,6 +65,8 @@ const ( // TaskGoroutineSchedInfo contains task goroutine scheduling state which must // be read and updated atomically. +// +// +stateify savable type TaskGoroutineSchedInfo struct { // Timestamp was the value of Kernel.cpuClock when this // TaskGoroutineSchedInfo was last updated. diff --git a/pkg/sentry/kernel/task_signals.go b/pkg/sentry/kernel/task_signals.go index 91f6c0874..62ec530be 100644 --- a/pkg/sentry/kernel/task_signals.go +++ b/pkg/sentry/kernel/task_signals.go @@ -748,6 +748,8 @@ func (t *Task) CopyInSignalStack(addr usermem.Addr) (arch.SignalStack, error) { // groupStop is a TaskStop placed on tasks that have received a stop signal // (SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU). (The term "group-stop" originates from // the ptrace man page.) +// +// +stateify savable type groupStop struct{} // Killable implements TaskStop.Killable. @@ -881,6 +883,8 @@ func (t *Task) signalStop(target *Task, code int32, status int32) { } // The runInterrupt state handles conditions indicated by interrupts. +// +// +stateify savable type runInterrupt struct{} func (*runInterrupt) execute(t *Task) taskRunState { @@ -1020,6 +1024,7 @@ func (*runInterrupt) execute(t *Task) taskRunState { return (*runApp)(nil) } +// +stateify savable type runInterruptAfterSignalDeliveryStop struct{} func (*runInterruptAfterSignalDeliveryStop) execute(t *Task) taskRunState { diff --git a/pkg/sentry/kernel/task_syscall.go b/pkg/sentry/kernel/task_syscall.go index 79f4ff60c..3b9652504 100644 --- a/pkg/sentry/kernel/task_syscall.go +++ b/pkg/sentry/kernel/task_syscall.go @@ -241,6 +241,7 @@ func (t *Task) doSyscallEnter(sysno uintptr, args arch.SyscallArguments) taskRun return t.doSyscallInvoke(sysno, args) } +// +stateify savable type runSyscallAfterSyscallEnterStop struct{} func (*runSyscallAfterSyscallEnterStop) execute(t *Task) taskRunState { @@ -260,6 +261,7 @@ func (*runSyscallAfterSyscallEnterStop) execute(t *Task) taskRunState { return t.doSyscallInvoke(sysno, args) } +// +stateify savable type runSyscallAfterSysemuStop struct{} func (*runSyscallAfterSysemuStop) execute(t *Task) taskRunState { @@ -294,6 +296,7 @@ func (t *Task) doSyscallInvoke(sysno uintptr, args arch.SyscallArguments) taskRu return (*runSyscallExit)(nil).execute(t) } +// +stateify savable type runSyscallReinvoke struct{} func (*runSyscallReinvoke) execute(t *Task) taskRunState { @@ -310,6 +313,7 @@ func (*runSyscallReinvoke) execute(t *Task) taskRunState { return t.doSyscallInvoke(sysno, args) } +// +stateify savable type runSyscallExit struct{} func (*runSyscallExit) execute(t *Task) taskRunState { diff --git a/pkg/sentry/kernel/thread_group.go b/pkg/sentry/kernel/thread_group.go index 8fffd3446..441b8a822 100644 --- a/pkg/sentry/kernel/thread_group.go +++ b/pkg/sentry/kernel/thread_group.go @@ -28,6 +28,8 @@ import ( // groups" are usually called "processes" in userspace documentation.) // // ThreadGroup is a superset of Linux's struct signal_struct. +// +// +stateify savable type ThreadGroup struct { threadGroupNode diff --git a/pkg/sentry/kernel/threads.go b/pkg/sentry/kernel/threads.go index 440da9dad..844213c35 100644 --- a/pkg/sentry/kernel/threads.go +++ b/pkg/sentry/kernel/threads.go @@ -50,6 +50,8 @@ func (tid ThreadID) String() string { const InitTID ThreadID = 1 // A TaskSet comprises all tasks in a system. +// +// +stateify savable type TaskSet struct { // mu protects all relationships betweens tasks and thread groups in the // TaskSet. (mu is approximately equivalent to Linux's tasklist_lock.) @@ -110,6 +112,8 @@ func (ts *TaskSet) forEachThreadGroupLocked(f func(tg *ThreadGroup)) { // // N.B. A task is said to be visible in a PID namespace if the PID namespace // contains a thread ID that maps to that task. +// +// +stateify savable type PIDNamespace struct { // owner is the TaskSet that this PID namespace belongs to. The owner // pointer is immutable. @@ -263,6 +267,8 @@ func (ns *PIDNamespace) UserNamespace() *auth.UserNamespace { // (threadGroupNode is an anonymous field in ThreadGroup; this is to expose // threadGroupEntry's methods on ThreadGroup to make it implement // threadGroupLinker.) +// +// +stateify savable type threadGroupNode struct { // pidns is the PID namespace containing the thread group and all of its // member tasks. The pidns pointer is immutable. @@ -382,6 +388,8 @@ func (tg *ThreadGroup) ID() ThreadID { // A taskNode defines the relationship between a task and the rest of the // system. The comments on threadGroupNode also apply to taskNode. +// +// +stateify savable type taskNode struct { // tg is the thread group that this task belongs to. The tg pointer is // immutable. diff --git a/pkg/sentry/kernel/time/BUILD b/pkg/sentry/kernel/time/BUILD index b3ed42aa4..5d8db2273 100644 --- a/pkg/sentry/kernel/time/BUILD +++ b/pkg/sentry/kernel/time/BUILD @@ -1,30 +1,18 @@ package(licenses = ["notice"]) # Apache 2.0 -load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify") - -go_stateify( - name = "time_state", - srcs = [ - "time.go", - ], - out = "time_state.go", - package = "time", -) +load("//tools/go_stateify:defs.bzl", "go_library") go_library( name = "time", srcs = [ "context.go", "time.go", - "time_state.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/time", visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/abi/linux", - "//pkg/log", "//pkg/sentry/context", - "//pkg/state", "//pkg/syserror", "//pkg/waiter", ], diff --git a/pkg/sentry/kernel/time/time.go b/pkg/sentry/kernel/time/time.go index c223c2f19..6eadd2878 100644 --- a/pkg/sentry/kernel/time/time.go +++ b/pkg/sentry/kernel/time/time.go @@ -42,6 +42,8 @@ const ( // // Time may represent time with respect to any clock and may not have any // meaning in the real world. +// +// +stateify savable type Time struct { ns int64 } @@ -286,6 +288,8 @@ type TimerListener interface { } // Setting contains user-controlled mutable Timer properties. +// +// +stateify savable type Setting struct { // Enabled is true if the timer is running. Enabled bool @@ -371,6 +375,8 @@ func (s Setting) advancedTo(now Time) (Setting, uint64) { // // Timers should be created using NewTimer and must be cleaned up by calling // Timer.Destroy when no longer used. +// +// +stateify savable type Timer struct { // clock is the time source. clock is immutable. clock Clock diff --git a/pkg/sentry/kernel/timekeeper.go b/pkg/sentry/kernel/timekeeper.go index 4de8ac13b..df5dbe128 100644 --- a/pkg/sentry/kernel/timekeeper.go +++ b/pkg/sentry/kernel/timekeeper.go @@ -25,6 +25,8 @@ import ( ) // Timekeeper manages all of the kernel clocks. +// +// +stateify savable type Timekeeper struct { // clocks are the clock sources. // diff --git a/pkg/sentry/kernel/timer.go b/pkg/sentry/kernel/timer.go index 03a3310be..534d03d0f 100644 --- a/pkg/sentry/kernel/timer.go +++ b/pkg/sentry/kernel/timer.go @@ -26,6 +26,8 @@ import ( // timekeeperClock is a ktime.Clock that reads time from a // kernel.Timekeeper-managed clock. +// +// +stateify savable type timekeeperClock struct { tk *Timekeeper c sentrytime.ClockID @@ -49,6 +51,8 @@ func (tc *timekeeperClock) Now() ktime.Time { // tgClock is a ktime.Clock that measures the time a thread group has spent // executing. +// +// +stateify savable type tgClock struct { tg *ThreadGroup @@ -155,6 +159,8 @@ func (tc *taskClock) Now() ktime.Time { } // signalNotifier is a ktime.Listener that sends signals to a ThreadGroup. +// +// +stateify savable type signalNotifier struct { tg *ThreadGroup signal linux.Signal @@ -179,6 +185,8 @@ func (s *signalNotifier) Notify(exp uint64) { func (s *signalNotifier) Destroy() {} // TimerManager is a collection of supported process cpu timers. +// +// +stateify savable type TimerManager struct { // Clocks used to drive thread group execution time timers. virtClock *tgClock diff --git a/pkg/sentry/kernel/uts_namespace.go b/pkg/sentry/kernel/uts_namespace.go index 58e9b4d1b..7e0fe0d21 100644 --- a/pkg/sentry/kernel/uts_namespace.go +++ b/pkg/sentry/kernel/uts_namespace.go @@ -22,6 +22,8 @@ import ( // UTSNamespace represents a UTS namespace, a holder of two system identifiers: // the hostname and domain name. +// +// +stateify savable type UTSNamespace struct { // mu protects all fields below. mu sync.Mutex `state:"nosave"` diff --git a/pkg/sentry/kernel/vdso.go b/pkg/sentry/kernel/vdso.go index 0bacbea49..971e8bc59 100644 --- a/pkg/sentry/kernel/vdso.go +++ b/pkg/sentry/kernel/vdso.go @@ -52,6 +52,8 @@ type vdsoParams struct { // Everything in the struct is 8 bytes for easy alignment. // // It must be kept in sync with params in vdso/vdso_time.cc. +// +// +stateify savable type VDSOParamPage struct { // The parameter page is fr, allocated from platform.Memory(). platform platform.Platform |