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:
parent
42a98de252
commit
9a01272dc2
@ -583,13 +583,10 @@ func untrustedWorkload(config *runtime.PodSandboxConfig) bool {
|
|||||||
return config.GetAnnotations()[annotations.UntrustedWorkload] == "true"
|
return config.GetAnnotations()[annotations.UntrustedWorkload] == "true"
|
||||||
}
|
}
|
||||||
|
|
||||||
// hostPrivilegedSandbox returns true if the sandbox configuration
|
// hostAccessingSandbox returns true if the sandbox configuration
|
||||||
// requires additional host privileges for the sandbox.
|
// requires additional host access for the sandbox.
|
||||||
func hostPrivilegedSandbox(config *runtime.PodSandboxConfig) bool {
|
func hostAccessingSandbox(config *runtime.PodSandboxConfig) bool {
|
||||||
securityContext := config.GetLinux().GetSecurityContext()
|
securityContext := config.GetLinux().GetSecurityContext()
|
||||||
if securityContext.GetPrivileged() {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
namespaceOptions := securityContext.GetNamespaceOptions()
|
namespaceOptions := securityContext.GetNamespaceOptions()
|
||||||
if namespaceOptions.GetNetwork() == runtime.NamespaceMode_NODE ||
|
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) {
|
func (c *criService) getSandboxRuntime(config *runtime.PodSandboxConfig) (criconfig.Runtime, error) {
|
||||||
untrusted := false
|
untrusted := false
|
||||||
if untrustedWorkload(config) {
|
if untrustedWorkload(config) {
|
||||||
// TODO(random-liu): Figure out we should return error or not.
|
// If the untrusted workload is requesting access to the host/node, this request will fail.
|
||||||
if hostPrivilegedSandbox(config) {
|
//
|
||||||
return criconfig.Runtime{}, errors.New("untrusted workload with host privilege is not allowed")
|
// 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
|
untrusted = true
|
||||||
}
|
}
|
||||||
|
@ -474,7 +474,7 @@ func TestTypeurlMarshalUnmarshalSandboxMeta(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHostPrivilegedSandbox(t *testing.T) {
|
func TestHostAccessingSandbox(t *testing.T) {
|
||||||
privilegedContext := &runtime.PodSandboxConfig{
|
privilegedContext := &runtime.PodSandboxConfig{
|
||||||
Linux: &runtime.LinuxPodSandboxConfig{
|
Linux: &runtime.LinuxPodSandboxConfig{
|
||||||
SecurityContext: &runtime.LinuxSandboxSecurityContext{
|
SecurityContext: &runtime.LinuxSandboxSecurityContext{
|
||||||
@ -507,14 +507,14 @@ func TestHostPrivilegedSandbox(t *testing.T) {
|
|||||||
want bool
|
want bool
|
||||||
}{
|
}{
|
||||||
{"Security Context is nil", nil, false},
|
{"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 is not privileged", nonPrivilegedContext, false},
|
||||||
{"Security Context namespace host access", hostNamespace, true},
|
{"Security Context namespace host access", hostNamespace, true},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
if got := hostPrivilegedSandbox(tt.config); got != tt.want {
|
if got := hostAccessingSandbox(tt.config); got != tt.want {
|
||||||
t.Errorf("hostPrivilegedSandbox() = %v, want %v", got, tt.want)
|
t.Errorf("hostAccessingSandbox() = %v, want %v", got, tt.want)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -540,11 +540,16 @@ func TestGetSandboxRuntime(t *testing.T) {
|
|||||||
expectErr bool
|
expectErr bool
|
||||||
expectedRuntime criconfig.Runtime
|
expectedRuntime criconfig.Runtime
|
||||||
}{
|
}{
|
||||||
"should return error if untrusted workload requires host privilege": {
|
"should return error if untrusted workload requires host access": {
|
||||||
sandboxConfig: &runtime.PodSandboxConfig{
|
sandboxConfig: &runtime.PodSandboxConfig{
|
||||||
Linux: &runtime.LinuxPodSandboxConfig{
|
Linux: &runtime.LinuxPodSandboxConfig{
|
||||||
SecurityContext: &runtime.LinuxSandboxSecurityContext{
|
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{
|
Annotations: map[string]string{
|
||||||
|
Loading…
Reference in New Issue
Block a user