Skip to content

Commit 697cb97

Browse files
authored
Merge pull request #1370 from mrunalp/update_spec_rc5
Update runtime spec to rc5
2 parents 31980a5 + 4f903a2 commit 697cb97

24 files changed

+439
-232
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ static: $(SOURCES)
4141
CGO_ENABLED=1 go build -i -tags "$(BUILDTAGS) cgo static_build" -ldflags "-w -extldflags -static -X main.gitCommit=${COMMIT} -X main.version=${VERSION}" -o contrib/cmd/recvtty/recvtty ./contrib/cmd/recvtty
4242

4343
release:
44-
@flag_list=(seccomp selinux apparmor static ambient); \
44+
@flag_list=(seccomp selinux apparmor static); \
4545
unset expression; \
4646
for flag in "$${flag_list[@]}"; do \
4747
expression+="' '{'',$${flag}}"; \

exec.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,13 @@ func getProcess(context *cli.Context, bundle string) (*specs.Process, error) {
176176
p.SelinuxLabel = l
177177
}
178178
if caps := context.StringSlice("cap"); len(caps) > 0 {
179-
p.Capabilities = caps
179+
for _, c := range caps {
180+
p.Capabilities.Bounding = append(p.Capabilities.Bounding, c)
181+
p.Capabilities.Inheritable = append(p.Capabilities.Inheritable, c)
182+
p.Capabilities.Effective = append(p.Capabilities.Effective, c)
183+
p.Capabilities.Permitted = append(p.Capabilities.Permitted, c)
184+
p.Capabilities.Ambient = append(p.Capabilities.Ambient, c)
185+
}
180186
}
181187
// append the passed env variables
182188
p.Env = append(p.Env, context.StringSlice("env")...)

libcontainer/capabilities_ambient.go

Lines changed: 0 additions & 7 deletions
This file was deleted.

libcontainer/capabilities_linux.go

Lines changed: 67 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@ import (
77
"os"
88
"strings"
99

10+
"github.com/opencontainers/runc/libcontainer/configs"
1011
"github.com/syndtr/gocapability/capability"
1112
)
1213

14+
const allCapabilityTypes = capability.CAPS | capability.BOUNDS | capability.AMBS
15+
1316
var capabilityMap map[string]capability.Cap
1417

1518
func init() {
@@ -28,40 +31,84 @@ func init() {
2831
}
2932
}
3033

31-
func newCapWhitelist(caps []string) (*whitelist, error) {
32-
l := []capability.Cap{}
33-
for _, c := range caps {
34+
func newContainerCapList(capConfig *configs.Capabilities) (*containerCapabilities, error) {
35+
bounding := []capability.Cap{}
36+
for _, c := range capConfig.Bounding {
37+
v, ok := capabilityMap[c]
38+
if !ok {
39+
return nil, fmt.Errorf("unknown capability %q", c)
40+
}
41+
bounding = append(bounding, v)
42+
}
43+
effective := []capability.Cap{}
44+
for _, c := range capConfig.Effective {
45+
v, ok := capabilityMap[c]
46+
if !ok {
47+
return nil, fmt.Errorf("unknown capability %q", c)
48+
}
49+
effective = append(effective, v)
50+
}
51+
inheritable := []capability.Cap{}
52+
for _, c := range capConfig.Inheritable {
53+
v, ok := capabilityMap[c]
54+
if !ok {
55+
return nil, fmt.Errorf("unknown capability %q", c)
56+
}
57+
inheritable = append(inheritable, v)
58+
}
59+
permitted := []capability.Cap{}
60+
for _, c := range capConfig.Permitted {
61+
v, ok := capabilityMap[c]
62+
if !ok {
63+
return nil, fmt.Errorf("unknown capability %q", c)
64+
}
65+
permitted = append(permitted, v)
66+
}
67+
ambient := []capability.Cap{}
68+
for _, c := range capConfig.Ambient {
3469
v, ok := capabilityMap[c]
3570
if !ok {
3671
return nil, fmt.Errorf("unknown capability %q", c)
3772
}
38-
l = append(l, v)
73+
ambient = append(ambient, v)
3974
}
4075
pid, err := capability.NewPid(os.Getpid())
4176
if err != nil {
4277
return nil, err
4378
}
44-
return &whitelist{
45-
keep: l,
46-
pid: pid,
79+
return &containerCapabilities{
80+
bounding: bounding,
81+
effective: effective,
82+
inheritable: inheritable,
83+
permitted: permitted,
84+
ambient: ambient,
85+
pid: pid,
4786
}, nil
4887
}
4988

50-
type whitelist struct {
51-
pid capability.Capabilities
52-
keep []capability.Cap
89+
type containerCapabilities struct {
90+
pid capability.Capabilities
91+
bounding []capability.Cap
92+
effective []capability.Cap
93+
inheritable []capability.Cap
94+
permitted []capability.Cap
95+
ambient []capability.Cap
5396
}
5497

55-
// dropBoundingSet drops the capability bounding set to those specified in the whitelist.
56-
func (w *whitelist) dropBoundingSet() error {
57-
w.pid.Clear(capability.BOUNDS)
58-
w.pid.Set(capability.BOUNDS, w.keep...)
59-
return w.pid.Apply(capability.BOUNDS)
98+
// ApplyBoundingSet sets the capability bounding set to those specified in the whitelist.
99+
func (c *containerCapabilities) ApplyBoundingSet() error {
100+
c.pid.Clear(capability.BOUNDS)
101+
c.pid.Set(capability.BOUNDS, c.bounding...)
102+
return c.pid.Apply(capability.BOUNDS)
60103
}
61104

62-
// drop drops all capabilities for the current process except those specified in the whitelist.
63-
func (w *whitelist) drop() error {
64-
w.pid.Clear(allCapabilityTypes)
65-
w.pid.Set(allCapabilityTypes, w.keep...)
66-
return w.pid.Apply(allCapabilityTypes)
105+
// Apply sets all the capabilities for the current process in the config.
106+
func (c *containerCapabilities) ApplyCaps() error {
107+
c.pid.Clear(allCapabilityTypes)
108+
c.pid.Set(capability.BOUNDS, c.bounding...)
109+
c.pid.Set(capability.PERMITTED, c.permitted...)
110+
c.pid.Set(capability.INHERITABLE, c.inheritable...)
111+
c.pid.Set(capability.EFFECTIVE, c.effective...)
112+
c.pid.Set(capability.AMBIENT, c.ambient...)
113+
return c.pid.Apply(allCapabilityTypes)
67114
}

libcontainer/capabilities_noambient.go

Lines changed: 0 additions & 7 deletions
This file was deleted.

libcontainer/configs/config.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,8 @@ type Config struct {
113113
Namespaces Namespaces `json:"namespaces"`
114114

115115
// Capabilities specify the capabilities to keep when executing the process inside the container
116-
// All capbilities not specified will be dropped from the processes capability mask
117-
Capabilities []string `json:"capabilities"`
116+
// All capabilities not specified will be dropped from the processes capability mask
117+
Capabilities *Capabilities `json:"capabilities"`
118118

119119
// Networks specifies the container's network setup to be created
120120
Networks []*Network `json:"networks"`
@@ -197,6 +197,19 @@ type Hooks struct {
197197
Poststop []Hook
198198
}
199199

200+
type Capabilities struct {
201+
// Bounding is the set of capabilities checked by the kernel.
202+
Bounding []string
203+
// Effective is the set of capabilities checked by the kernel.
204+
Effective []string
205+
// Inheritable is the capabilities preserved across execve.
206+
Inheritable []string
207+
// Permitted is the limiting superset for effective capabilities.
208+
Permitted []string
209+
// Ambient is the ambient set of capabilities that are kept.
210+
Ambient []string
211+
}
212+
200213
func (hooks *Hooks) UnmarshalJSON(b []byte) error {
201214
var state struct {
202215
Prestart []CommandHook

libcontainer/configs/config_test.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -120,10 +120,10 @@ func TestMarshalHooksWithUnexpectedType(t *testing.T) {
120120

121121
func TestFuncHookRun(t *testing.T) {
122122
state := configs.HookState{
123-
Version: "1",
124-
ID: "1",
125-
Pid: 1,
126-
BundlePath: "/bundle",
123+
Version: "1",
124+
ID: "1",
125+
Pid: 1,
126+
Bundle: "/bundle",
127127
}
128128

129129
fHook := configs.NewFunctionHook(func(s configs.HookState) error {
@@ -138,10 +138,10 @@ func TestFuncHookRun(t *testing.T) {
138138

139139
func TestCommandHookRun(t *testing.T) {
140140
state := configs.HookState{
141-
Version: "1",
142-
ID: "1",
143-
Pid: 1,
144-
BundlePath: "/bundle",
141+
Version: "1",
142+
ID: "1",
143+
Pid: 1,
144+
Bundle: "/bundle",
145145
}
146146
timeout := time.Second
147147

@@ -161,10 +161,10 @@ func TestCommandHookRun(t *testing.T) {
161161

162162
func TestCommandHookRunTimeout(t *testing.T) {
163163
state := configs.HookState{
164-
Version: "1",
165-
ID: "1",
166-
Pid: 1,
167-
BundlePath: "/bundle",
164+
Version: "1",
165+
ID: "1",
166+
Pid: 1,
167+
Bundle: "/bundle",
168168
}
169169
timeout := (10 * time.Millisecond)
170170

libcontainer/container_linux.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -275,10 +275,10 @@ func (c *linuxContainer) start(process *Process, isInit bool) error {
275275

276276
if c.config.Hooks != nil {
277277
s := configs.HookState{
278-
Version: c.config.Version,
279-
ID: c.id,
280-
Pid: parent.pid(),
281-
BundlePath: utils.SearchLabels(c.config.Labels, "bundle"),
278+
Version: c.config.Version,
279+
ID: c.id,
280+
Pid: parent.pid(),
281+
Bundle: utils.SearchLabels(c.config.Labels, "bundle"),
282282
}
283283
for i, hook := range c.config.Hooks.Poststart {
284284
if err := hook.Run(s); err != nil {
@@ -1157,10 +1157,10 @@ func (c *linuxContainer) criuNotifications(resp *criurpc.CriuResp, process *Proc
11571157
case notify.GetScript() == "setup-namespaces":
11581158
if c.config.Hooks != nil {
11591159
s := configs.HookState{
1160-
Version: c.config.Version,
1161-
ID: c.id,
1162-
Pid: int(notify.GetPid()),
1163-
BundlePath: utils.SearchLabels(c.config.Labels, "bundle"),
1160+
Version: c.config.Version,
1161+
ID: c.id,
1162+
Pid: int(notify.GetPid()),
1163+
Bundle: utils.SearchLabels(c.config.Labels, "bundle"),
11641164
}
11651165
for i, hook := range c.config.Hooks.Prestart {
11661166
if err := hook.Run(s); err != nil {

libcontainer/init_linux.go

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -45,21 +45,21 @@ type network struct {
4545

4646
// initConfig is used for transferring parameters from Exec() to Init()
4747
type initConfig struct {
48-
Args []string `json:"args"`
49-
Env []string `json:"env"`
50-
Cwd string `json:"cwd"`
51-
Capabilities []string `json:"capabilities"`
52-
ProcessLabel string `json:"process_label"`
53-
AppArmorProfile string `json:"apparmor_profile"`
54-
NoNewPrivileges bool `json:"no_new_privileges"`
55-
User string `json:"user"`
56-
AdditionalGroups []string `json:"additional_groups"`
57-
Config *configs.Config `json:"config"`
58-
Networks []*network `json:"network"`
59-
PassedFilesCount int `json:"passed_files_count"`
60-
ContainerId string `json:"containerid"`
61-
Rlimits []configs.Rlimit `json:"rlimits"`
62-
CreateConsole bool `json:"create_console"`
48+
Args []string `json:"args"`
49+
Env []string `json:"env"`
50+
Cwd string `json:"cwd"`
51+
Capabilities *configs.Capabilities `json:"capabilities"`
52+
ProcessLabel string `json:"process_label"`
53+
AppArmorProfile string `json:"apparmor_profile"`
54+
NoNewPrivileges bool `json:"no_new_privileges"`
55+
User string `json:"user"`
56+
AdditionalGroups []string `json:"additional_groups"`
57+
Config *configs.Config `json:"config"`
58+
Networks []*network `json:"network"`
59+
PassedFilesCount int `json:"passed_files_count"`
60+
ContainerId string `json:"containerid"`
61+
Rlimits []configs.Rlimit `json:"rlimits"`
62+
CreateConsole bool `json:"create_console"`
6363
}
6464

6565
type initer interface {
@@ -121,12 +121,12 @@ func finalizeNamespace(config *initConfig) error {
121121
if config.Capabilities != nil {
122122
capabilities = config.Capabilities
123123
}
124-
w, err := newCapWhitelist(capabilities)
124+
w, err := newContainerCapList(capabilities)
125125
if err != nil {
126126
return err
127127
}
128128
// drop capabilities in bounding set before changing user
129-
if err := w.dropBoundingSet(); err != nil {
129+
if err := w.ApplyBoundingSet(); err != nil {
130130
return err
131131
}
132132
// preserve existing capabilities while we change users
@@ -139,8 +139,7 @@ func finalizeNamespace(config *initConfig) error {
139139
if err := system.ClearKeepCaps(); err != nil {
140140
return err
141141
}
142-
// drop all other capabilities
143-
if err := w.drop(); err != nil {
142+
if err := w.ApplyCaps(); err != nil {
144143
return err
145144
}
146145
if config.Cwd != "" {

0 commit comments

Comments
 (0)