Skip to content
This repository was archived by the owner on Aug 14, 2020. It is now read-only.

Commit dab935e

Browse files
committed
Merge pull request #611 from s-urbaniak/no-new-privs
spec: implement os/linux/no-new-privs isolator
2 parents e9daa59 + 1dfb9e4 commit dab935e

File tree

5 files changed

+102
-5
lines changed

5 files changed

+102
-5
lines changed

actool/manifest.go

+13-1
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,19 @@ func patchManifest(im *schema.ImageManifest) error {
258258
return fmt.Errorf("cannot parse isolator %q: %v", is, err)
259259
}
260260

261-
if _, ok := types.ResourceIsolatorNames[name]; !ok {
261+
_, ok := types.ResourceIsolatorNames[name]
262+
263+
if name == types.LinuxNoNewPrivilegesName {
264+
ok = true
265+
kv := strings.Split(is, ",")
266+
if len(kv) != 2 {
267+
return fmt.Errorf("isolator %s: invalid format", name)
268+
}
269+
270+
isolatorStr = fmt.Sprintf(`{ "name": "%s", "value": %s }`, name, kv[1])
271+
}
272+
273+
if !ok {
262274
return fmt.Errorf("isolator %s is not supported for patching", name)
263275
}
264276

examples/image.json

+4
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@
5656
{
5757
"name": "os/linux/capabilities-retain-set",
5858
"value": {"set": ["CAP_NET_ADMIN", "CAP_NET_BIND_SERVICE"]}
59+
},
60+
{
61+
"name": "os/linux/no-new-privileges",
62+
"value": true
5963
}
6064
],
6165
"mountPoints": [

schema/types/isolator_linux_specific.go

+20
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
const (
2323
LinuxCapabilitiesRetainSetName = "os/linux/capabilities-retain-set"
2424
LinuxCapabilitiesRevokeSetName = "os/linux/capabilities-remove-set"
25+
LinuxNoNewPrivilegesName = "os/linux/no-new-privileges"
2526
)
2627

2728
var LinuxIsolatorNames = make(map[ACIdentifier]struct{})
@@ -30,12 +31,31 @@ func init() {
3031
for name, con := range map[ACIdentifier]IsolatorValueConstructor{
3132
LinuxCapabilitiesRevokeSetName: func() IsolatorValue { return &LinuxCapabilitiesRevokeSet{} },
3233
LinuxCapabilitiesRetainSetName: func() IsolatorValue { return &LinuxCapabilitiesRetainSet{} },
34+
LinuxNoNewPrivilegesName: func() IsolatorValue { v := LinuxNoNewPrivileges(false); return &v },
3335
} {
3436
AddIsolatorName(name, LinuxIsolatorNames)
3537
AddIsolatorValueConstructor(name, con)
3638
}
3739
}
3840

41+
type LinuxNoNewPrivileges bool
42+
43+
func (l LinuxNoNewPrivileges) AssertValid() error {
44+
return nil
45+
}
46+
47+
func (l *LinuxNoNewPrivileges) UnmarshalJSON(b []byte) error {
48+
var v bool
49+
err := json.Unmarshal(b, &v)
50+
if err != nil {
51+
return err
52+
}
53+
54+
*l = LinuxNoNewPrivileges(v)
55+
56+
return nil
57+
}
58+
3959
type LinuxCapabilitiesSet interface {
4060
Set() []LinuxCapability
4161
AssertValid() error

schema/types/isolator_test.go

+50-4
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,41 @@ func TestIsolatorUnmarshal(t *testing.T) {
2525
msg string
2626
werr bool
2727
}{
28+
{
29+
`{
30+
"name": "os/linux/no-new-privileges",
31+
"value": true
32+
}`,
33+
false,
34+
},
35+
{
36+
`{
37+
"name": "os/linux/no-new-privileges",
38+
"value": false
39+
}`,
40+
false,
41+
},
42+
{
43+
`{
44+
"name": "os/linux/no-new-privileges",
45+
"value": 123
46+
}`,
47+
true,
48+
},
49+
{
50+
`{
51+
"name": "os/linux/no-new-privileges",
52+
"value": {"set": ["CAP_KILL"]}
53+
}`,
54+
true,
55+
},
56+
{
57+
`{
58+
"name": "os/linux/no-new-privileges",
59+
"value": "foo"
60+
}`,
61+
true,
62+
},
2863
{
2964
`{
3065
"name": "os/linux/capabilities-retain-set",
@@ -166,6 +201,10 @@ func TestIsolatorsGetByName(t *testing.T) {
166201
{
167202
"name": "os/linux/capabilities-remove-set",
168203
"value": {"set": ["CAP_KILL"]}
204+
},
205+
{
206+
"name": "os/linux/no-new-privileges",
207+
"value": true
169208
}
170209
]
171210
`
@@ -175,11 +214,13 @@ func TestIsolatorsGetByName(t *testing.T) {
175214
wlimit int64
176215
wrequest int64
177216
wset []LinuxCapability
217+
wprivs LinuxNoNewPrivileges
178218
}{
179-
{"resource/cpu", 1, 30, nil},
180-
{"resource/memory", 2147483648, 1000000000, nil},
181-
{"os/linux/capabilities-retain-set", 0, 0, []LinuxCapability{"CAP_KILL"}},
182-
{"os/linux/capabilities-remove-set", 0, 0, []LinuxCapability{"CAP_KILL"}},
219+
{"resource/cpu", 1, 30, nil, false},
220+
{"resource/memory", 2147483648, 1000000000, nil, false},
221+
{"os/linux/capabilities-retain-set", 0, 0, []LinuxCapability{"CAP_KILL"}, false},
222+
{"os/linux/capabilities-remove-set", 0, 0, []LinuxCapability{"CAP_KILL"}, false},
223+
{"os/linux/no-new-privileges", 0, 0, nil, LinuxNoNewPrivileges(true)},
183224
}
184225

185226
var is Isolators
@@ -223,6 +264,11 @@ func TestIsolatorsGetByName(t *testing.T) {
223264
t.Errorf("#%d: gset=%v, want %v", i, s.Set(), tt.wset)
224265
}
225266

267+
case *LinuxNoNewPrivileges:
268+
if tt.wprivs != *v {
269+
t.Errorf("#%d: got %v, want %v", i, v, tt.wprivs)
270+
}
271+
226272
default:
227273
panic("unexecpected type")
228274
}

spec/ace.md

+15
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,21 @@ Listing a capability in the remove set that is not in the default set such as `C
195195
In the example above, the process will only have the two capabilities in its bounding set.
196196
The retain set cannot be used in conjunction with the remove set.
197197

198+
#### os/linux/no-new-privileges
199+
200+
* Scope: app
201+
202+
If set to true the app's process and all its children can never gain new privileges. For details see the corresponding kernel documentation about [prctl/no_new_privs.txt](https://www.kernel.org/doc/Documentation/prctl/no_new_privs.txt).
203+
204+
The default value is `false`.
205+
206+
```json
207+
"name": "os/linux/no-new-privileges",
208+
"value": true
209+
```
210+
211+
In the example above, the process will have `no_new_privs` set. If the app's executable has i.e. setuid/setgid bits set they will be ignored.
212+
198213
### Resource Isolators
199214

200215
A _resource_ is something that can be consumed by an application (app) or group of applications (pod), such as memory (RAM), CPU, and network bandwidth.

0 commit comments

Comments
 (0)