Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 121 additions & 5 deletions src/agent/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 12 additions & 7 deletions src/agent/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ protocols = { path = "../libs/protocols", features = ["async", "with-serde"] }
lazy_static = "1.3.0"
ttrpc = { version = "0.7.1", features = ["async"], default-features = false }
protobuf = "3.2.0"
libc = "0.2.58"
libc = "0.2.147"
nix = "0.24.2"
capctl = "0.2.0"
serde_json = "1.0.39"
Expand Down Expand Up @@ -74,17 +74,21 @@ serde = { version = "1.0.129", features = ["derive"] }
toml = "0.5.8"
clap = { version = "3.0.1", features = ["derive"] }

# "vendored" feature for openssl is required by musl build
openssl = "0.10.54"
openssl-src = "111.26.0"

# OPA requests
http = "0.2.8"
reqwest = { version = "0.11.14" }
http = { version = "0.2.8", optional = true }
reqwest = { version = "0.11.14", optional = true }
# "vendored" feature for openssl is required by musl build
openssl = { version = "0.10.54", features = ["vendored"], optional = true }

# Image pull/decrypt
image-rs = { git = "https://github.com/confidential-containers/image-rs", tag = "v0.6.0", default-features = false, features = ["kata-cc-native-tls"] }

# Policy validation
sha2 = { version = "0.10.6", optional = true }
hex = { version = "0.4.2", optional = true }
sev = { git = "https://github.com/virtee/sev", version = "1.2", default-features = false, features = ["snp"], optional = true }

[patch.crates-io]
oci-distribution = { git = "https://github.com/krustlet/oci-distribution.git", rev = "f44124c" }

Expand All @@ -103,9 +107,10 @@ members = [
lto = true

[features]
default = []
seccomp = ["rustjail/seccomp"]
standard-oci-runtime = ["rustjail/standard-oci-runtime"]
security-policy = []
security-policy = ["hex", "http", "openssl", "reqwest", "sev", "sha2"]

[[bin]]
name = "kata-agent"
Expand Down
26 changes: 25 additions & 1 deletion src/agent/src/policy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
// SPDX-License-Identifier: Apache-2.0
//

use anyhow::{anyhow, Result};
use anyhow::{anyhow, bail, Result};
use reqwest::Client;
use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
use tokio::io::AsyncWriteExt;
use tokio::time::{sleep, Duration};

Expand Down Expand Up @@ -106,6 +107,8 @@ impl AgentPolicy {

/// Replace the Policy in OPA.
pub async fn set_policy(&mut self, policy: &str) -> Result<()> {
check_policy_hash(policy)?;

// Delete the old rules.
self.opa_client
.delete(&self.policy_path)
Expand Down Expand Up @@ -195,3 +198,24 @@ impl AgentPolicy {
}
}
}

pub fn check_policy_hash(policy: &str) -> Result<()> {
let mut hasher = Sha256::new();
hasher.update(policy.as_bytes());
let digest = hasher.finalize();
debug!(sl!(), "policy: calculated hash ({:?})", digest.as_slice());

let mut firmware = sev::firmware::guest::Firmware::open()?;
let report_data: [u8; 64] = [0; 64];
let report = firmware.get_report(None, Some(report_data), Some(0))?;

if report.host_data != digest.as_slice() {
bail!(
"Unexpected policy hash ({:?}), expected ({:?})",
digest.as_slice(),
report.host_data
);
}

Ok(())
}
8 changes: 6 additions & 2 deletions src/runtime/virtcontainers/clh.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ const (
clhAPISocket = "clh-api.sock"
virtioFsSocket = "virtiofsd.sock"
defaultClhPath = "/usr/local/bin/cloud-hypervisor"
snpHostDataDummy = "0123456789012345678901234567890123456789012345678901234567890123"
snpZeroHostData = "0000000000000000000000000000000000000000000000000000000000000000"
)

// Interface that hides the implementation of openAPI client
Expand Down Expand Up @@ -458,7 +458,11 @@ func (clh *cloudHypervisor) enableProtection() error {
}
clh.vmconfig.Platform.SetSnp(true)

clh.vmconfig.Payload.SetHostData(snpHostDataDummy)
if len(clh.config.PolicyHash) > 0 {
clh.vmconfig.Payload.SetHostData(clh.config.PolicyHash)
} else {
clh.vmconfig.Payload.SetHostData(snpZeroHostData)
}

return nil

Expand Down
1 change: 1 addition & 0 deletions src/runtime/virtcontainers/hypervisor.go
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,7 @@ type HypervisorConfig struct {
DisableGuestSeLinux bool
LegacySerial bool
ColdPlugVFIO hv.PCIePort
PolicyHash string
}

// vcpu mapping from vcpu number to thread number
Expand Down
14 changes: 14 additions & 0 deletions src/runtime/virtcontainers/sandbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"bufio"
"bytes"
"context"
"crypto/sha256"
"encoding/hex"
"fmt"
"io"
"math"
Expand Down Expand Up @@ -647,6 +649,8 @@ func newSandbox(ctx context.Context, sandboxConfig SandboxConfig, factory Factor
}
}

sandboxConfig.HypervisorConfig.PolicyHash = getAgentPolicyHash(sandboxConfig.AgentConfig.Policy)

// store doesn't require hypervisor to be stored immediately
if err = s.hypervisor.CreateVM(ctx, s.id, s.network, &sandboxConfig.HypervisorConfig); err != nil {
return nil, err
Expand Down Expand Up @@ -2702,3 +2706,13 @@ func (s *Sandbox) resetVCPUsPinning(ctx context.Context, vCPUThreadsMap VcpuThre
func (s *Sandbox) PullImage(ctx context.Context, req *image.PullImageReq) (*image.PullImageResp, error) {
return s.agent.PullImage(ctx, req)
}

func getAgentPolicyHash(policy string) string {
if len(policy) == 0 {
return ""
} else {
h := sha256.New()
h.Write([]byte(policy))
return hex.EncodeToString(h.Sum(nil))
}
}