sandbox: separate host accessing workload and privileged

VM isolated runtimes can support privileged workloads. In this
scenario, access to the guest VM is provided instead of the host.
Based on this, allow untrusted runtimes to run privileged workloads.

If the workload is specifically asking for node PID/IPC/network, etc.,
then continue to require the trusted runtime.

This commit repurposes the hostPrivilegedSandbox utility function to
only check for node namespace checking.

Fixes: #855

Signed-off-by: Eric Ernst <eric.ernst@intel.com>
This commit is contained in:
Eric Ernst 2018-07-20 09:01:02 -07:00
parent 42a98de252
commit 9a01272dc2
2 changed files with 21 additions and 15 deletions

View File

@ -583,13 +583,10 @@ func untrustedWorkload(config *runtime.PodSandboxConfig) bool {
return config.GetAnnotations()[annotations.UntrustedWorkload] == "true"
}
// hostPrivilegedSandbox returns true if the sandbox configuration
// requires additional host privileges for the sandbox.
func hostPrivilegedSandbox(config *runtime.PodSandboxConfig) bool {
// hostAccessingSandbox returns true if the sandbox configuration
// requires additional host access for the sandbox.
func hostAccessingSandbox(config *runtime.PodSandboxConfig) bool {
securityContext := config.GetLinux().GetSecurityContext()
if securityContext.GetPrivileged() {
return true
}
namespaceOptions := securityContext.GetNamespaceOptions()
if namespaceOptions.GetNetwork() == runtime.NamespaceMode_NODE ||
@ -607,9 +604,13 @@ func hostPrivilegedSandbox(config *runtime.PodSandboxConfig) bool {
func (c *criService) getSandboxRuntime(config *runtime.PodSandboxConfig) (criconfig.Runtime, error) {
untrusted := false
if untrustedWorkload(config) {
// TODO(random-liu): Figure out we should return error or not.
if hostPrivilegedSandbox(config) {
return criconfig.Runtime{}, errors.New("untrusted workload with host privilege is not allowed")
// If the untrusted workload is requesting access to the host/node, this request will fail.
//
// Note: If the workload is marked untrusted but requests privileged, this can be granted, as the
// runtime may support this. For example, in a virtual-machine isolated runtime, privileged
// is a supported option, granting the workload to access the entire guest VM instead of host.
if hostAccessingSandbox(config) {
return criconfig.Runtime{}, errors.New("untrusted workload with host access is not allowed")
}
untrusted = true
}

View File

@ -474,7 +474,7 @@ func TestTypeurlMarshalUnmarshalSandboxMeta(t *testing.T) {
}
}
func TestHostPrivilegedSandbox(t *testing.T) {
func TestHostAccessingSandbox(t *testing.T) {
privilegedContext := &runtime.PodSandboxConfig{
Linux: &runtime.LinuxPodSandboxConfig{
SecurityContext: &runtime.LinuxSandboxSecurityContext{
@ -507,14 +507,14 @@ func TestHostPrivilegedSandbox(t *testing.T) {
want bool
}{
{"Security Context is nil", nil, false},
{"Security Context is privileged", privilegedContext, true},
{"Security Context is privileged", privilegedContext, false},
{"Security Context is not privileged", nonPrivilegedContext, false},
{"Security Context namespace host access", hostNamespace, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := hostPrivilegedSandbox(tt.config); got != tt.want {
t.Errorf("hostPrivilegedSandbox() = %v, want %v", got, tt.want)
if got := hostAccessingSandbox(tt.config); got != tt.want {
t.Errorf("hostAccessingSandbox() = %v, want %v", got, tt.want)
}
})
}
@ -540,11 +540,16 @@ func TestGetSandboxRuntime(t *testing.T) {
expectErr bool
expectedRuntime criconfig.Runtime
}{
"should return error if untrusted workload requires host privilege": {
"should return error if untrusted workload requires host access": {
sandboxConfig: &runtime.PodSandboxConfig{
Linux: &runtime.LinuxPodSandboxConfig{
SecurityContext: &runtime.LinuxSandboxSecurityContext{
Privileged: true,
Privileged: false,
NamespaceOptions: &runtime.NamespaceOption{
Network: runtime.NamespaceMode_NODE,
Pid: runtime.NamespaceMode_NODE,
Ipc: runtime.NamespaceMode_NODE,
},
},
},
Annotations: map[string]string{