summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/kernel/task.go
diff options
context:
space:
mode:
authorJamie Liu <jamieliu@google.com>2018-08-31 13:57:02 -0700
committerShentubot <shentubot@google.com>2018-08-31 13:58:04 -0700
commit098046ba193b839d69c059f7a0e68c89409b4237 (patch)
tree22a6bfcdbb4d440ef067c8df4643ef26f7255be1 /pkg/sentry/kernel/task.go
parentb1c1afa3ccc499df3fd15814d2b6cf9005bc2ab1 (diff)
Disintegrate kernel.TaskResources.
This allows us to call kernel.FDMap.DecRef without holding mutexes cleanly. PiperOrigin-RevId: 211139657 Change-Id: Ie59d5210fb9282e1950e2e40323df7264a01bcec
Diffstat (limited to 'pkg/sentry/kernel/task.go')
-rw-r--r--pkg/sentry/kernel/task.go131
1 files changed, 95 insertions, 36 deletions
diff --git a/pkg/sentry/kernel/task.go b/pkg/sentry/kernel/task.go
index 21be3120e..32db0bf48 100644
--- a/pkg/sentry/kernel/task.go
+++ b/pkg/sentry/kernel/task.go
@@ -99,6 +99,19 @@ type Task struct {
// ThreadGroup.signalHandlers.
pendingSignals pendingSignals
+ // signalMask is the set of signals whose delivery is currently blocked.
+ //
+ // signalMask is accessed using atomic memory operations, and is protected
+ // by the signal mutex (such that reading signalMask is safe if either the
+ // signal mutex is locked or if atomic memory operations are used, while
+ // writing signalMask requires both). signalMask is owned by the task
+ // goroutine.
+ signalMask linux.SignalSet
+
+ // FIXME: An equivalent to task_struct::real_blocked is needed
+ // to prevent signals that are ignored, but transiently unblocked by
+ // sigtimedwait(2), from being dropped in Task.sendSignalTimerLocked.
+
// If haveSavedSignalMask is true, savedSignalMask is the signal mask that
// should be applied after the task has either delivered one signal to a
// user handler or is about to resume execution in the untrusted
@@ -182,25 +195,30 @@ type Task struct {
// syscallRestartBlock is exclusive to the task goroutine.
syscallRestartBlock SyscallRestartBlock
+ // p provides the mechanism by which the task runs code in userspace. The p
+ // interface object is immutable.
+ p platform.Context `state:"nosave"`
+
+ // k is the Kernel that this task belongs to. The k pointer is immutable.
+ k *Kernel
+
// mu protects some of the following fields.
mu sync.Mutex `state:"nosave"`
- // tc and tr form the majority of the task's data.
+ // tc holds task data provided by the ELF loader.
//
- // tc and tr are protected by mu. tc and tr are owned by the task
- // goroutine. tr.signalMask is protected by the signal mutex and must be
- // written using atomic memory operations (such that reading tr.signalMask
- // is safe if the signal mutex is locked or if atomic memory operations are
- // used), but is also owned by the task goroutine.
+ // tc is protected by mu, and is owned by the task goroutine.
tc TaskContext
- tr TaskResources
- // p provides the mechanism by which the task runs code in userspace. The p
- // interface object is immutable.
- p platform.Context `state:"nosave"`
+ // fsc is the task's filesystem context.
+ //
+ // fsc is protected by mu, and is owned by the task goroutine.
+ fsc *FSContext
- // k is the Kernel that this task belongs to. The k pointer is immutable.
- k *Kernel
+ // fds is the task's file descriptor table.
+ //
+ // fds is protected by mu, and is owned by the task goroutine.
+ fds *FDMap
// If vforkParent is not nil, it is the task that created this task with
// vfork() or clone(CLONE_VFORK), and should have its vforkStop ended when
@@ -351,6 +369,11 @@ type Task struct {
// ipcns is protected by mu.
ipcns *IPCNamespace
+ // abstractSockets tracks abstract sockets that are in use.
+ //
+ // abstractSockets is protected by mu.
+ abstractSockets *AbstractSocketNamespace
+
// parentDeathSignal is sent to this task's thread group when its parent exits.
//
// parentDeathSignal is protected by mu.
@@ -518,29 +541,6 @@ func (t *Task) FutexWaiter() *futex.Waiter {
return t.futexWaiter
}
-// TaskContext returns t's TaskContext.
-//
-// Precondition: The caller must be running on the task goroutine, or t.mu must
-// be locked.
-func (t *Task) TaskContext() *TaskContext {
- return &t.tc
-}
-
-// TaskResources returns t's TaskResources.
-//
-// Precondition: The caller must be running on the task goroutine, or t.mu must
-// be locked.
-func (t *Task) TaskResources() *TaskResources {
- return &t.tr
-}
-
-// WithMuLocked executes f with t.mu locked.
-func (t *Task) WithMuLocked(f func(*Task)) {
- t.mu.Lock()
- defer t.mu.Unlock()
- f(t)
-}
-
// Kernel returns the Kernel containing t.
func (t *Task) Kernel() *Kernel {
return t.k
@@ -572,7 +572,7 @@ func (t *Task) Value(key interface{}) interface{} {
case context.CtxThreadGroupID:
return int32(t.ThreadGroup().ID())
case fs.CtxRoot:
- return t.FSContext().RootDirectory()
+ return t.fsc.RootDirectory()
case inet.CtxStack:
return t.NetworkContext()
case ktime.CtxRealtimeClock:
@@ -619,3 +619,62 @@ func (t *Task) SyscallRestartBlock() SyscallRestartBlock {
t.syscallRestartBlock = nil
return r
}
+
+// IsChrooted returns true if the root directory of t's FSContext is not the
+// root directory of t's MountNamespace.
+//
+// Preconditions: The caller must be running on the task goroutine, or t.mu
+// must be locked.
+func (t *Task) IsChrooted() bool {
+ realRoot := t.k.mounts.Root()
+ defer realRoot.DecRef()
+ root := t.fsc.RootDirectory()
+ if root != nil {
+ defer root.DecRef()
+ }
+ return root != realRoot
+}
+
+// TaskContext returns t's TaskContext.
+//
+// Precondition: The caller must be running on the task goroutine, or t.mu must
+// be locked.
+func (t *Task) TaskContext() *TaskContext {
+ return &t.tc
+}
+
+// FSContext returns t's FSContext. FSContext does not take an additional
+// reference on the returned FSContext.
+//
+// Precondition: The caller must be running on the task goroutine, or t.mu must
+// be locked.
+func (t *Task) FSContext() *FSContext {
+ return t.fsc
+}
+
+// FDMap returns t's FDMap. FDMap does not take an additional reference on the
+// returned FDMap.
+//
+// Precondition: The caller must be running on the task goroutine, or t.mu must
+// be locked.
+func (t *Task) FDMap() *FDMap {
+ return t.fds
+}
+
+// WithMuLocked executes f with t.mu locked.
+func (t *Task) WithMuLocked(f func(*Task)) {
+ t.mu.Lock()
+ defer t.mu.Unlock()
+ f(t)
+}
+
+// MountNamespace returns t's MountNamespace. MountNamespace does not take an
+// additional reference on the returned MountNamespace.
+func (t *Task) MountNamespace() *fs.MountNamespace {
+ return t.k.mounts
+}
+
+// AbstractSockets returns t's AbstractSocketNamespace.
+func (t *Task) AbstractSockets() *AbstractSocketNamespace {
+ return t.abstractSockets
+}