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

Commit

Permalink
spec: implement os/linux/no-new-privs isolator
Browse files Browse the repository at this point in the history
This adds a new no-new-privs isolator type.

actool support was added for patching a manifest:
`actool patch-manifest -isolators='os/linux/no-new-privs,true'`.

This is a prerequisite for rkt/rkt#1469.
  • Loading branch information
s-urbaniak committed May 24, 2016
1 parent e9daa59 commit 2c53732
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 5 deletions.
14 changes: 13 additions & 1 deletion actool/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,19 @@ func patchManifest(im *schema.ImageManifest) error {
return fmt.Errorf("cannot parse isolator %q: %v", is, err)
}

if _, ok := types.ResourceIsolatorNames[name]; !ok {
_, ok := types.ResourceIsolatorNames[name]

if name == types.LinuxNoNewPrivsName {
ok = true
kv := strings.Split(is, ",")
if len(kv) != 2 {
return fmt.Errorf("isolator %s: invalid format", name)
}

isolatorStr = fmt.Sprintf(`{ "name": "%s", "value": %s }`, name, kv[1])
}

if !ok {
return fmt.Errorf("isolator %s is not supported for patching", name)
}

Expand Down
4 changes: 4 additions & 0 deletions examples/image.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@
{
"name": "os/linux/capabilities-retain-set",
"value": {"set": ["CAP_NET_ADMIN", "CAP_NET_BIND_SERVICE"]}
},
{
"name": "os/linux/no-new-privs",
"value": true
}
],
"mountPoints": [
Expand Down
20 changes: 20 additions & 0 deletions schema/types/isolator_linux_specific.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
const (
LinuxCapabilitiesRetainSetName = "os/linux/capabilities-retain-set"
LinuxCapabilitiesRevokeSetName = "os/linux/capabilities-remove-set"
LinuxNoNewPrivsName = "os/linux/no-new-privs"
)

var LinuxIsolatorNames = make(map[ACIdentifier]struct{})
Expand All @@ -30,12 +31,31 @@ func init() {
for name, con := range map[ACIdentifier]IsolatorValueConstructor{
LinuxCapabilitiesRevokeSetName: func() IsolatorValue { return &LinuxCapabilitiesRevokeSet{} },
LinuxCapabilitiesRetainSetName: func() IsolatorValue { return &LinuxCapabilitiesRetainSet{} },
LinuxNoNewPrivsName: func() IsolatorValue { v := LinuxNoNewPrivs(false); return &v },
} {
AddIsolatorName(name, LinuxIsolatorNames)
AddIsolatorValueConstructor(name, con)
}
}

type LinuxNoNewPrivs bool

func (l LinuxNoNewPrivs) AssertValid() error {
return nil
}

func (l *LinuxNoNewPrivs) UnmarshalJSON(b []byte) error {
var v bool
err := json.Unmarshal(b, &v)
if err != nil {
return err
}

*l = LinuxNoNewPrivs(v)

return nil
}

type LinuxCapabilitiesSet interface {
Set() []LinuxCapability
AssertValid() error
Expand Down
54 changes: 50 additions & 4 deletions schema/types/isolator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,41 @@ func TestIsolatorUnmarshal(t *testing.T) {
msg string
werr bool
}{
{
`{
"name": "os/linux/no-new-privs",
"value": true
}`,
false,
},
{
`{
"name": "os/linux/no-new-privs",
"value": false
}`,
false,
},
{
`{
"name": "os/linux/no-new-privs",
"value": 123
}`,
true,
},
{
`{
"name": "os/linux/no-new-privs",
"value": {"set": ["CAP_KILL"]}
}`,
true,
},
{
`{
"name": "os/linux/no-new-privs",
"value": "foo"
}`,
true,
},
{
`{
"name": "os/linux/capabilities-retain-set",
Expand Down Expand Up @@ -166,6 +201,10 @@ func TestIsolatorsGetByName(t *testing.T) {
{
"name": "os/linux/capabilities-remove-set",
"value": {"set": ["CAP_KILL"]}
},
{
"name": "os/linux/no-new-privs",
"value": true
}
]
`
Expand All @@ -175,11 +214,13 @@ func TestIsolatorsGetByName(t *testing.T) {
wlimit int64
wrequest int64
wset []LinuxCapability
wprivs LinuxNoNewPrivs
}{
{"resource/cpu", 1, 30, nil},
{"resource/memory", 2147483648, 1000000000, nil},
{"os/linux/capabilities-retain-set", 0, 0, []LinuxCapability{"CAP_KILL"}},
{"os/linux/capabilities-remove-set", 0, 0, []LinuxCapability{"CAP_KILL"}},
{"resource/cpu", 1, 30, nil, false},
{"resource/memory", 2147483648, 1000000000, nil, false},
{"os/linux/capabilities-retain-set", 0, 0, []LinuxCapability{"CAP_KILL"}, false},
{"os/linux/capabilities-remove-set", 0, 0, []LinuxCapability{"CAP_KILL"}, false},
{"os/linux/no-new-privs", 0, 0, nil, LinuxNoNewPrivs(true)},
}

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

case *LinuxNoNewPrivs:
if tt.wprivs != *v {
t.Errorf("#%d: got %v, want %v", i, v, tt.wprivs)
}

default:
panic("unexecpected type")
}
Expand Down
13 changes: 13 additions & 0 deletions spec/ace.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,19 @@ Listing a capability in the remove set that is not in the default set such as `C
In the example above, the process will only have the two capabilities in its bounding set.
The retain set cannot be used in conjunction with the remove set.

#### os/linux/no-new-privs

* Scope: app

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).

```json
"name": "os/linux/no-new-privs",
"value": true
```

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.

### Resource Isolators

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.
Expand Down

0 comments on commit 2c53732

Please sign in to comment.