diff options
Diffstat (limited to 'pkg/sentry/kernel')
-rwxr-xr-x | pkg/sentry/kernel/epoll/epoll_state_autogen.go | 28 | ||||
-rwxr-xr-x | pkg/sentry/kernel/eventfd/eventfd_state_autogen.go | 4 | ||||
-rwxr-xr-x | pkg/sentry/kernel/futex/futex_state_autogen.go | 8 | ||||
-rwxr-xr-x | pkg/sentry/kernel/kernel_state_autogen.go | 23 | ||||
-rwxr-xr-x | pkg/sentry/kernel/semaphore/semaphore_state_autogen.go | 4 | ||||
-rw-r--r-- | pkg/sentry/kernel/syscalls.go | 33 | ||||
-rw-r--r-- | pkg/sentry/kernel/syscalls_state.go | 36 | ||||
-rw-r--r-- | pkg/sentry/kernel/task_context.go | 2 | ||||
-rw-r--r-- | pkg/sentry/kernel/time/time.go | 10 |
9 files changed, 83 insertions, 65 deletions
diff --git a/pkg/sentry/kernel/epoll/epoll_state_autogen.go b/pkg/sentry/kernel/epoll/epoll_state_autogen.go index afdea5bcf..da3150465 100755 --- a/pkg/sentry/kernel/epoll/epoll_state_autogen.go +++ b/pkg/sentry/kernel/epoll/epoll_state_autogen.go @@ -43,26 +43,26 @@ func (x *pollEntry) load(m state.Map) { func (x *EventPoll) beforeSave() {} func (x *EventPoll) save(m state.Map) { x.beforeSave() - if !state.IsZeroValue(x.FilePipeSeek) { - m.Failf("FilePipeSeek is %v, expected zero", x.FilePipeSeek) + if !state.IsZeroValue(&x.FilePipeSeek) { + m.Failf("FilePipeSeek is %#v, expected zero", &x.FilePipeSeek) } - if !state.IsZeroValue(x.FileNotDirReaddir) { - m.Failf("FileNotDirReaddir is %v, expected zero", x.FileNotDirReaddir) + if !state.IsZeroValue(&x.FileNotDirReaddir) { + m.Failf("FileNotDirReaddir is %#v, expected zero", &x.FileNotDirReaddir) } - if !state.IsZeroValue(x.FileNoFsync) { - m.Failf("FileNoFsync is %v, expected zero", x.FileNoFsync) + if !state.IsZeroValue(&x.FileNoFsync) { + m.Failf("FileNoFsync is %#v, expected zero", &x.FileNoFsync) } - if !state.IsZeroValue(x.FileNoopFlush) { - m.Failf("FileNoopFlush is %v, expected zero", x.FileNoopFlush) + if !state.IsZeroValue(&x.FileNoopFlush) { + m.Failf("FileNoopFlush is %#v, expected zero", &x.FileNoopFlush) } - if !state.IsZeroValue(x.FileNoIoctl) { - m.Failf("FileNoIoctl is %v, expected zero", x.FileNoIoctl) + if !state.IsZeroValue(&x.FileNoIoctl) { + m.Failf("FileNoIoctl is %#v, expected zero", &x.FileNoIoctl) } - if !state.IsZeroValue(x.FileNoMMap) { - m.Failf("FileNoMMap is %v, expected zero", x.FileNoMMap) + if !state.IsZeroValue(&x.FileNoMMap) { + m.Failf("FileNoMMap is %#v, expected zero", &x.FileNoMMap) } - if !state.IsZeroValue(x.Queue) { - m.Failf("Queue is %v, expected zero", x.Queue) + if !state.IsZeroValue(&x.Queue) { + m.Failf("Queue is %#v, expected zero", &x.Queue) } m.Save("files", &x.files) m.Save("readyList", &x.readyList) diff --git a/pkg/sentry/kernel/eventfd/eventfd_state_autogen.go b/pkg/sentry/kernel/eventfd/eventfd_state_autogen.go index 9cf0ac817..636d80ea9 100755 --- a/pkg/sentry/kernel/eventfd/eventfd_state_autogen.go +++ b/pkg/sentry/kernel/eventfd/eventfd_state_autogen.go @@ -9,8 +9,8 @@ import ( func (x *EventOperations) beforeSave() {} func (x *EventOperations) save(m state.Map) { x.beforeSave() - if !state.IsZeroValue(x.wq) { - m.Failf("wq is %v, expected zero", x.wq) + if !state.IsZeroValue(&x.wq) { + m.Failf("wq is %#v, expected zero", &x.wq) } m.Save("val", &x.val) m.Save("semMode", &x.semMode) diff --git a/pkg/sentry/kernel/futex/futex_state_autogen.go b/pkg/sentry/kernel/futex/futex_state_autogen.go index d5ed3466f..68aa69daa 100755 --- a/pkg/sentry/kernel/futex/futex_state_autogen.go +++ b/pkg/sentry/kernel/futex/futex_state_autogen.go @@ -21,8 +21,8 @@ func (x *AtomicPtrBucket) load(m state.Map) { func (x *bucket) beforeSave() {} func (x *bucket) save(m state.Map) { x.beforeSave() - if !state.IsZeroValue(x.waiters) { - m.Failf("waiters is %v, expected zero", x.waiters) + if !state.IsZeroValue(&x.waiters) { + m.Failf("waiters is %#v, expected zero", &x.waiters) } } @@ -33,8 +33,8 @@ func (x *bucket) load(m state.Map) { func (x *Manager) beforeSave() {} func (x *Manager) save(m state.Map) { x.beforeSave() - if !state.IsZeroValue(x.privateBuckets) { - m.Failf("privateBuckets is %v, expected zero", x.privateBuckets) + if !state.IsZeroValue(&x.privateBuckets) { + m.Failf("privateBuckets is %#v, expected zero", &x.privateBuckets) } m.Save("sharedBucket", &x.sharedBucket) } diff --git a/pkg/sentry/kernel/kernel_state_autogen.go b/pkg/sentry/kernel/kernel_state_autogen.go index 21a0bbf81..a5b00130c 100755 --- a/pkg/sentry/kernel/kernel_state_autogen.go +++ b/pkg/sentry/kernel/kernel_state_autogen.go @@ -511,17 +511,17 @@ func (x *socketEntry) load(m state.Map) { m.Load("prev", &x.prev) } -func (x *SyscallTable) beforeSave() {} -func (x *SyscallTable) save(m state.Map) { +func (x *syscallTableInfo) beforeSave() {} +func (x *syscallTableInfo) save(m state.Map) { x.beforeSave() m.Save("OS", &x.OS) m.Save("Arch", &x.Arch) } -func (x *SyscallTable) load(m state.Map) { - m.LoadWait("OS", &x.OS) - m.LoadWait("Arch", &x.Arch) - m.AfterLoad(x.afterLoad) +func (x *syscallTableInfo) afterLoad() {} +func (x *syscallTableInfo) load(m state.Map) { + m.Load("OS", &x.OS) + m.Load("Arch", &x.Arch) } func (x *syslog) beforeSave() {} @@ -538,8 +538,8 @@ func (x *syslog) load(m state.Map) { func (x *Task) beforeSave() {} func (x *Task) save(m state.Map) { x.beforeSave() - if !state.IsZeroValue(x.signalQueue) { - m.Failf("signalQueue is %v, expected zero", x.signalQueue) + if !state.IsZeroValue(&x.signalQueue) { + m.Failf("signalQueue is %#v, expected zero", &x.signalQueue) } var ptraceTracer *Task = x.savePtraceTracer() m.SaveValue("ptraceTracer", ptraceTracer) @@ -701,11 +701,12 @@ func (x *vforkStop) load(m state.Map) { func (x *TaskContext) beforeSave() {} func (x *TaskContext) save(m state.Map) { x.beforeSave() + var st syscallTableInfo = x.saveSt() + m.SaveValue("st", st) m.Save("Name", &x.Name) m.Save("Arch", &x.Arch) m.Save("MemoryManager", &x.MemoryManager) m.Save("fu", &x.fu) - m.Save("st", &x.st) } func (x *TaskContext) afterLoad() {} @@ -714,7 +715,7 @@ func (x *TaskContext) load(m state.Map) { m.Load("Arch", &x.Arch) m.Load("MemoryManager", &x.MemoryManager) m.Load("fu", &x.fu) - m.Load("st", &x.st) + m.LoadValue("st", new(syscallTableInfo), func(y interface{}) { x.loadSt(y.(syscallTableInfo)) }) } func (x *execStop) beforeSave() {} @@ -1194,7 +1195,7 @@ func init() { state.Register("pkg/sentry/kernel.SignalHandlers", (*SignalHandlers)(nil), state.Fns{Save: (*SignalHandlers).save, Load: (*SignalHandlers).load}) state.Register("pkg/sentry/kernel.socketList", (*socketList)(nil), state.Fns{Save: (*socketList).save, Load: (*socketList).load}) state.Register("pkg/sentry/kernel.socketEntry", (*socketEntry)(nil), state.Fns{Save: (*socketEntry).save, Load: (*socketEntry).load}) - state.Register("pkg/sentry/kernel.SyscallTable", (*SyscallTable)(nil), state.Fns{Save: (*SyscallTable).save, Load: (*SyscallTable).load}) + state.Register("pkg/sentry/kernel.syscallTableInfo", (*syscallTableInfo)(nil), state.Fns{Save: (*syscallTableInfo).save, Load: (*syscallTableInfo).load}) state.Register("pkg/sentry/kernel.syslog", (*syslog)(nil), state.Fns{Save: (*syslog).save, Load: (*syslog).load}) state.Register("pkg/sentry/kernel.Task", (*Task)(nil), state.Fns{Save: (*Task).save, Load: (*Task).load}) state.Register("pkg/sentry/kernel.runSyscallAfterPtraceEventClone", (*runSyscallAfterPtraceEventClone)(nil), state.Fns{Save: (*runSyscallAfterPtraceEventClone).save, Load: (*runSyscallAfterPtraceEventClone).load}) diff --git a/pkg/sentry/kernel/semaphore/semaphore_state_autogen.go b/pkg/sentry/kernel/semaphore/semaphore_state_autogen.go index db80a1490..ba1d073d9 100755 --- a/pkg/sentry/kernel/semaphore/semaphore_state_autogen.go +++ b/pkg/sentry/kernel/semaphore/semaphore_state_autogen.go @@ -53,8 +53,8 @@ func (x *Set) load(m state.Map) { func (x *sem) beforeSave() {} func (x *sem) save(m state.Map) { x.beforeSave() - if !state.IsZeroValue(x.waiters) { - m.Failf("waiters is %v, expected zero", x.waiters) + if !state.IsZeroValue(&x.waiters) { + m.Failf("waiters is %#v, expected zero", &x.waiters) } m.Save("value", &x.value) m.Save("pid", &x.pid) diff --git a/pkg/sentry/kernel/syscalls.go b/pkg/sentry/kernel/syscalls.go index 93c4fe969..c9a2321b8 100644 --- a/pkg/sentry/kernel/syscalls.go +++ b/pkg/sentry/kernel/syscalls.go @@ -218,56 +218,55 @@ type Stracer interface { SyscallExit(context interface{}, t *Task, sysno, rval uintptr, err error) } -// 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. +// SyscallTable is a lookup table of system calls. // -// +stateify savable +// Note that a SyscallTable is not savable directly. Instead, they are saved as +// an OS/Arch pair and lookup happens again on restore. type SyscallTable struct { // OS is the operating system that this syscall table implements. - OS abi.OS `state:"wait"` + OS abi.OS // Arch is the architecture that this syscall table targets. - Arch arch.Arch `state:"wait"` + Arch arch.Arch // The OS version that this syscall table implements. - Version Version `state:"manual"` + Version Version // AuditNumber is a numeric constant that represents the syscall table. If // non-zero, auditNumber must be one of the AUDIT_ARCH_* values defined by // linux/audit.h. - AuditNumber uint32 `state:"manual"` + AuditNumber uint32 // Table is the collection of functions. - Table map[uintptr]Syscall `state:"manual"` + Table map[uintptr]Syscall // lookup is a fixed-size array that holds the syscalls (indexed by // their numbers). It is used for fast look ups. - lookup []SyscallFn `state:"manual"` + lookup []SyscallFn // Emulate is a collection of instruction addresses to emulate. The // keys are addresses, and the values are system call numbers. - Emulate map[usermem.Addr]uintptr `state:"manual"` + Emulate map[usermem.Addr]uintptr // The function to call in case of a missing system call. - Missing MissingFn `state:"manual"` + Missing MissingFn // Stracer traces this syscall table. - Stracer Stracer `state:"manual"` + Stracer Stracer // External is used to handle an external callback. - External func(*Kernel) `state:"manual"` + External func(*Kernel) // ExternalFilterBefore is called before External is called before the syscall is executed. // External is not called if it returns false. - ExternalFilterBefore func(*Task, uintptr, arch.SyscallArguments) bool `state:"manual"` + ExternalFilterBefore func(*Task, uintptr, arch.SyscallArguments) bool // ExternalFilterAfter is called before External is called after the syscall is executed. // External is not called if it returns false. - ExternalFilterAfter func(*Task, uintptr, arch.SyscallArguments) bool `state:"manual"` + ExternalFilterAfter func(*Task, uintptr, arch.SyscallArguments) bool // FeatureEnable stores the strace and one-shot enable bits. - FeatureEnable SyscallFlagsTable `state:"manual"` + FeatureEnable SyscallFlagsTable } // allSyscallTables contains all known tables. diff --git a/pkg/sentry/kernel/syscalls_state.go b/pkg/sentry/kernel/syscalls_state.go index 00358326b..90f890495 100644 --- a/pkg/sentry/kernel/syscalls_state.go +++ b/pkg/sentry/kernel/syscalls_state.go @@ -14,16 +14,34 @@ package kernel -import "fmt" +import ( + "fmt" -// afterLoad is invoked by stateify. -func (s *SyscallTable) afterLoad() { - otherTable, ok := LookupSyscallTable(s.OS, s.Arch) - if !ok { - // Couldn't find a reference? - panic(fmt.Sprintf("syscall table not found for OS %v Arch %v", s.OS, s.Arch)) + "gvisor.dev/gvisor/pkg/abi" + "gvisor.dev/gvisor/pkg/sentry/arch" +) + +// syscallTableInfo is used to reload the SyscallTable. +// +// +stateify savable +type syscallTableInfo struct { + OS abi.OS + Arch arch.Arch +} + +// saveSt saves the SyscallTable. +func (tc *TaskContext) saveSt() syscallTableInfo { + return syscallTableInfo{ + OS: tc.st.OS, + Arch: tc.st.Arch, } +} - // Copy the table. - *s = *otherTable +// loadSt loads the SyscallTable. +func (tc *TaskContext) loadSt(sti syscallTableInfo) { + st, ok := LookupSyscallTable(sti.OS, sti.Arch) + if !ok { + panic(fmt.Sprintf("syscall table not found for OS %v, Arch %v", sti.OS, sti.Arch)) + } + tc.st = st // Save the table reference. } diff --git a/pkg/sentry/kernel/task_context.go b/pkg/sentry/kernel/task_context.go index 0158b1788..c115e8d1f 100644 --- a/pkg/sentry/kernel/task_context.go +++ b/pkg/sentry/kernel/task_context.go @@ -49,7 +49,7 @@ type TaskContext struct { fu *futex.Manager // st is the task's syscall table. - st *SyscallTable + st *SyscallTable `state:".(syscallTableInfo)"` } // release releases all resources held by the TaskContext. release is called by diff --git a/pkg/sentry/kernel/time/time.go b/pkg/sentry/kernel/time/time.go index 706de83ef..e959700f2 100644 --- a/pkg/sentry/kernel/time/time.go +++ b/pkg/sentry/kernel/time/time.go @@ -245,7 +245,7 @@ type Clock interface { type WallRateClock struct{} // WallTimeUntil implements Clock.WallTimeUntil. -func (WallRateClock) WallTimeUntil(t, now Time) time.Duration { +func (*WallRateClock) WallTimeUntil(t, now Time) time.Duration { return t.Sub(now) } @@ -254,16 +254,16 @@ func (WallRateClock) WallTimeUntil(t, now Time) time.Duration { type NoClockEvents struct{} // Readiness implements waiter.Waitable.Readiness. -func (NoClockEvents) Readiness(mask waiter.EventMask) waiter.EventMask { +func (*NoClockEvents) Readiness(mask waiter.EventMask) waiter.EventMask { return 0 } // EventRegister implements waiter.Waitable.EventRegister. -func (NoClockEvents) EventRegister(e *waiter.Entry, mask waiter.EventMask) { +func (*NoClockEvents) EventRegister(e *waiter.Entry, mask waiter.EventMask) { } // EventUnregister implements waiter.Waitable.EventUnregister. -func (NoClockEvents) EventUnregister(e *waiter.Entry) { +func (*NoClockEvents) EventUnregister(e *waiter.Entry) { } // ClockEventsQueue implements waiter.Waitable by wrapping waiter.Queue and @@ -273,7 +273,7 @@ type ClockEventsQueue struct { } // Readiness implements waiter.Waitable.Readiness. -func (ClockEventsQueue) Readiness(mask waiter.EventMask) waiter.EventMask { +func (*ClockEventsQueue) Readiness(mask waiter.EventMask) waiter.EventMask { return 0 } |