summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/kernel/task_resources.go
blob: 4ca25664a2e6a761e72091e7bab2550942062331 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Copyright 2018 Google Inc.
//
// 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 kernel

import (
	"gvisor.googlesource.com/gvisor/pkg/abi/linux"
	"gvisor.googlesource.com/gvisor/pkg/sentry/fs"
)

// TaskResources is the subset of a task's data provided by its creator that is
// not provided by the loader.
type TaskResources struct {
	// SignalMask is the set of signals whose delivery is currently blocked.
	//
	// FIXME: Determine if we also need RealSignalMask
	SignalMask linux.SignalSet

	// FSContext is the filesystem context.
	*FSContext

	// FDMap provides access to files to the task.
	*FDMap

	// Tracks abstract sockets that are in use.
	AbstractSockets *AbstractSocketNamespace
}

// newTaskResources returns a new TaskResources, taking an additional reference
// on fdm.
func newTaskResources(fdm *FDMap, fc *FSContext) *TaskResources {
	fdm.IncRef()
	return &TaskResources{
		FDMap:           fdm,
		FSContext:       fc,
		AbstractSockets: NewAbstractSocketNamespace(),
	}
}

// release releases all resources held by the TaskResources. release is called
// by the task when it exits.
func (tr *TaskResources) release() {
	tr.FDMap.DecRef()
	tr.FDMap = nil
	tr.FSContext.DecRef()
	tr.FSContext = nil
	tr.AbstractSockets = nil
}

// Fork returns a duplicate of tr.
//
// FIXME: Preconditions: When tr is owned by a Task, that task's
// signal mutex must be locked, or Fork must be called by the task's goroutine.
func (tr *TaskResources) Fork(shareFiles bool, shareFSContext bool) *TaskResources {
	var fdmap *FDMap
	if shareFiles {
		fdmap = tr.FDMap
		fdmap.IncRef()
	} else {
		fdmap = tr.FDMap.Fork()
	}

	var fsc *FSContext
	if shareFSContext {
		fsc = tr.FSContext
		fsc.IncRef()
	} else {
		fsc = tr.FSContext.Fork()
	}

	return &TaskResources{
		SignalMask:      tr.SignalMask,
		FDMap:           fdmap,
		FSContext:       fsc,
		AbstractSockets: tr.AbstractSockets,
	}
}

// FDMap returns t's FDMap.
//
// Preconditions: The caller must be running on the task goroutine, or t.mu
// must be locked.
func (t *Task) FDMap() *FDMap {
	return t.tr.FDMap
}

// FSContext returns t's FSContext.
//
// Preconditions: The caller must be running on the task goroutine, or t.mu
// must be locked.
func (t *Task) FSContext() *FSContext {
	return t.tr.FSContext
}

// 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.tr.AbstractSockets
}

// 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.tr.FSContext.RootDirectory()
	if root != nil {
		defer root.DecRef()
	}
	return root != realRoot
}