From 9a01272dc20faf723d905b50f66a5fc99d9af5f3 Mon Sep 17 00:00:00 2001 From: Eric Ernst Date: Fri, 20 Jul 2018 09:01:02 -0700 Subject: [PATCH] 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 --- pkg/server/sandbox_run.go | 19 ++++++++++--------- pkg/server/sandbox_run_test.go | 17 +++++++++++------ 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/pkg/server/sandbox_run.go b/pkg/server/sandbox_run.go index c445abae0..38f763223 100644 --- a/pkg/server/sandbox_run.go +++ b/pkg/server/sandbox_run.go @@ -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 } diff --git a/pkg/server/sandbox_run_test.go b/pkg/server/sandbox_run_test.go index b0c45ad19..56120de83 100644 --- a/pkg/server/sandbox_run_test.go +++ b/pkg/server/sandbox_run_test.go @@ -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{