diff --git a/docs/use-cases/using-Intel-SGX-and-kata.md b/docs/use-cases/using-Intel-SGX-and-kata.md index f45e3ed5bc..b08e3c765c 100644 --- a/docs/use-cases/using-Intel-SGX-and-kata.md +++ b/docs/use-cases/using-Intel-SGX-and-kata.md @@ -18,7 +18,7 @@ CONFIG_X86_SGX_KVM=y * Kubernetes cluster configured with: * [`kata-deploy`](../../tools/packaging/kata-deploy) based Kata Containers installation - * [Intel SGX Kubernetes device plugin](https://github.com/intel/intel-device-plugins-for-kubernetes/tree/main/cmd/sgx_plugin#deploying-with-pre-built-images) + * [Intel SGX Kubernetes device plugin](https://github.com/intel/intel-device-plugins-for-kubernetes/tree/main/cmd/sgx_plugin#deploying-with-pre-built-images) and associated components including [operator](https://github.com/intel/intel-device-plugins-for-kubernetes/blob/main/cmd/operator/README.md) and dependencies > Note: Kata Containers supports creating VM sandboxes with IntelĀ® SGX enabled > using [cloud-hypervisor](https://github.com/cloud-hypervisor/cloud-hypervisor/) and [QEMU](https://www.qemu.org/) VMMs only. @@ -99,4 +99,4 @@ because socket passthrough is not supported. An alternative is to deploy the `ae container. * Projects like [Gramine Shielded Containers (GSC)](https://gramine-gsc.readthedocs.io/en/latest/) are also known to work. For GSC specifically, the Kata guest kernel needs to have the `CONFIG_NUMA=y` -enabled and at least one CPU online when running the GSC container. +enabled and at least one CPU online when running the GSC container. The Kata Containers guest kernel currently has CONFIG_NUMA=y enabled by default. diff --git a/src/agent/Cargo.lock b/src/agent/Cargo.lock index ee32dc420b..e26f7bd032 100644 --- a/src/agent/Cargo.lock +++ b/src/agent/Cargo.lock @@ -629,9 +629,9 @@ dependencies = [ "libc", "log", "logging", - "netlink-packet-utils", - "netlink-sys", - "nix 0.24.1", + "netlink-packet-utils 0.4.1", + "netlink-sys 0.7.0", + "nix 0.24.2", "oci", "opentelemetry", "procfs", @@ -674,7 +674,7 @@ dependencies = [ "kata-types", "lazy_static", "libc", - "nix 0.24.1", + "nix 0.24.2", "oci", "once_cell", "rand 0.7.3", @@ -816,28 +816,28 @@ checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" [[package]] name = "netlink-packet-core" -version = "0.2.4" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac48279d5062bdf175bdbcb6b58ff1d6b0ecd54b951f7a0ff4bc0550fe903ccb" +checksum = "345b8ab5bd4e71a2986663e88c56856699d060e78e152e6e9d7966fcd5491297" dependencies = [ "anyhow", "byteorder", "libc", - "netlink-packet-utils", + "netlink-packet-utils 0.5.1", ] [[package]] name = "netlink-packet-route" -version = "0.8.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76aed5d3b6e3929713bf1e1334a11fd65180b6d9f5d7c8572664c48b122604f8" +checksum = "f5dee5ed749373c298237fe694eb0a51887f4cc1a27370c8464bac4382348f1a" dependencies = [ "anyhow", "bitflags", "byteorder", "libc", "netlink-packet-core", - "netlink-packet-utils", + "netlink-packet-utils 0.5.1", ] [[package]] @@ -853,18 +853,30 @@ dependencies = [ ] [[package]] -name = "netlink-proto" -version = "0.7.0" +name = "netlink-packet-utils" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd06e90449ae973fe3888c1ff85949604ef5189b4ac9a2ae39518da1e00762d" +checksum = "25af9cf0dc55498b7bd94a1508af7a78706aa0ab715a73c5169273e03c84845e" +dependencies = [ + "anyhow", + "byteorder", + "paste", + "thiserror", +] + +[[package]] +name = "netlink-proto" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65b4b14489ab424703c092062176d52ba55485a89c076b4f9db05092b7223aa6" dependencies = [ "bytes 1.1.0", "futures", "log", "netlink-packet-core", - "netlink-sys", + "netlink-sys 0.8.3", + "thiserror", "tokio", - "tokio-util", ] [[package]] @@ -879,6 +891,19 @@ dependencies = [ "tokio", ] +[[package]] +name = "netlink-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92b654097027250401127914afb37cb1f311df6610a9891ff07a757e94199027" +dependencies = [ + "bytes 1.1.0", + "futures", + "libc", + "log", + "tokio", +] + [[package]] name = "nix" version = "0.17.0" @@ -892,19 +917,6 @@ dependencies = [ "void", ] -[[package]] -name = "nix" -version = "0.22.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4916f159ed8e5de0082076562152a76b7a1f64a01fd9d1e0fea002c37624faf" -dependencies = [ - "bitflags", - "cc", - "cfg-if 1.0.0", - "libc", - "memoffset", -] - [[package]] name = "nix" version = "0.23.1" @@ -920,9 +932,9 @@ dependencies = [ [[package]] name = "nix" -version = "0.24.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f17df307904acd05aa8e32e97bb20f2a0df1728bbc2d771ae8f9a90463441e9" +checksum = "195cdbc1741b8134346d515b3a56a1c94b0912758009cfd53f99ea0f57b065fc" dependencies = [ "bitflags", "cfg-if 1.0.0", @@ -1467,15 +1479,15 @@ dependencies = [ [[package]] name = "rtnetlink" -version = "0.8.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c9a6200d18ec1acfc218ce71363dcc9b6075f399220f903fdfeacd476a876ef" +checksum = "46f1cfa18f8cebe685373a2697915d7e0db3b4554918bba118385e0f71f258a7" dependencies = [ "futures", "log", "netlink-packet-route", "netlink-proto", - "nix 0.22.3", + "nix 0.24.2", "thiserror", "tokio", ] @@ -1694,9 +1706,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "subprocess" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "055cf3ebc2981ad8f0a5a17ef6652f652d87831f79fddcba2ac57bcb9a0aa407" +checksum = "0c2e86926081dda636c546d8c5e641661049d7562a68f5488be4a1f7f66f6086" dependencies = [ "libc", "winapi", @@ -1856,20 +1868,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-util" -version = "0.6.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36943ee01a6d67977dd3f84a5a1d2efeb4ada3a1ae771cadfaa535d9d9fc6507" -dependencies = [ - "bytes 1.1.0", - "futures-core", - "futures-sink", - "log", - "pin-project-lite", - "tokio", -] - [[package]] name = "tokio-vsock" version = "0.3.1" diff --git a/src/agent/Cargo.toml b/src/agent/Cargo.toml index 1d20766b2e..166d080e9b 100644 --- a/src/agent/Cargo.toml +++ b/src/agent/Cargo.toml @@ -32,8 +32,8 @@ futures = "0.3.17" tokio = { version = "1.14.0", features = ["full"] } tokio-vsock = "0.3.1" -netlink-sys = { version = "0.7.0", features = ["tokio_socket"]} -rtnetlink = "0.8.0" +netlink-sys = { version = "0.7.0", features = ["tokio_socket",]} +rtnetlink = "0.11.0" netlink-packet-utils = "0.4.1" ipnetwork = "0.17.0" diff --git a/src/agent/src/netlink.rs b/src/agent/src/netlink.rs index c6fc9c2079..3869eee000 100644 --- a/src/agent/src/netlink.rs +++ b/src/agent/src/netlink.rs @@ -4,7 +4,7 @@ // use anyhow::{anyhow, Context, Result}; -use futures::{future, StreamExt, TryStreamExt}; +use futures::{future, TryStreamExt}; use ipnetwork::{IpNetwork, Ipv4Network, Ipv6Network}; use nix::errno::Errno; use protobuf::RepeatedField; @@ -164,7 +164,7 @@ impl Handle { let request = self.handle.link().get(); let filtered = match filter { - LinkFilter::Name(name) => request.set_name_filter(name.to_owned()), + LinkFilter::Name(name) => request.match_name(name.to_owned()), LinkFilter::Index(index) => request.match_index(index), _ => request, // Post filters }; @@ -516,7 +516,6 @@ impl Handle { } /// Adds an ARP neighbor. - /// TODO: `rtnetlink` has no neighbours API, remove this after https://github.com/little-dude/netlink/pull/135 async fn add_arp_neighbor(&mut self, neigh: &ARPNeighbor) -> Result<()> { let ip_address = neigh .toIPAddress @@ -528,58 +527,13 @@ impl Handle { let ip = IpAddr::from_str(ip_address) .map_err(|e| anyhow!("Failed to parse IP {}: {:?}", ip_address, e))?; - // Import rtnetlink objects that make sense only for this function - use packet::constants::{NDA_UNSPEC, NLM_F_ACK, NLM_F_CREATE, NLM_F_EXCL, NLM_F_REQUEST}; - use packet::neighbour::{NeighbourHeader, NeighbourMessage}; - use packet::nlas::neighbour::Nla; - use packet::{NetlinkMessage, NetlinkPayload, RtnlMessage}; - use rtnetlink::Error; - - const IFA_F_PERMANENT: u16 = 0x80; // See https://github.com/little-dude/netlink/blob/0185b2952505e271805902bf175fee6ea86c42b8/netlink-packet-route/src/rtnl/constants.rs#L770 - let link = self.find_link(LinkFilter::Name(&neigh.device)).await?; - let message = NeighbourMessage { - header: NeighbourHeader { - family: match ip { - IpAddr::V4(_) => packet::AF_INET, - IpAddr::V6(_) => packet::AF_INET6, - } as u8, - ifindex: link.index(), - state: if neigh.state != 0 { - neigh.state as u16 - } else { - IFA_F_PERMANENT - }, - flags: neigh.flags as u8, - ntype: NDA_UNSPEC as u8, - }, - nlas: { - let mut nlas = vec![Nla::Destination(match ip { - IpAddr::V4(v4) => v4.octets().to_vec(), - IpAddr::V6(v6) => v6.octets().to_vec(), - })]; - - if !neigh.lladdr.is_empty() { - nlas.push(Nla::LinkLocalAddress( - parse_mac_address(&neigh.lladdr)?.to_vec(), - )); - } - - nlas - }, - }; - - // Send request and ACK - let mut req = NetlinkMessage::from(RtnlMessage::NewNeighbour(message)); - req.header.flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE; - - let mut response = self.handle.request(req)?; - while let Some(message) = response.next().await { - if let NetlinkPayload::Error(err) = message.payload { - return Err(anyhow!(Error::NetlinkError(err))); - } - } + self.handle + .neighbours() + .add(link.index(), ip) + .execute() + .await?; Ok(()) } @@ -950,7 +904,7 @@ mod tests { .expect("prepare: failed to delete neigh"); } - fn prepare_env_for_test_add_one_arp_neighbor(dummy_name: &str, ip: &str) { + fn prepare_env_for_test_add_one_arp_neighbor(dummy_name: &str, ip: &str, mac: &str) { clean_env_for_test_add_one_arp_neighbor(dummy_name, ip); // modprobe dummy Command::new("modprobe") @@ -964,6 +918,12 @@ mod tests { .output() .expect("failed to add dummy interface"); + // ip link set dummy address 6a:92:3a:59:70:aa + Command::new("ip") + .args(&["link", "set", dummy_name, "address", mac]) + .output() + .expect("failed to add dummy interface"); + // ip addr add 192.168.0.2/16 dev dummy Command::new("ip") .args(&["addr", "add", "192.168.0.2/16", "dev", dummy_name]) @@ -985,7 +945,7 @@ mod tests { let to_ip = "169.254.1.1"; let dummy_name = "dummy_for_arp"; - prepare_env_for_test_add_one_arp_neighbor(dummy_name, to_ip); + prepare_env_for_test_add_one_arp_neighbor(dummy_name, to_ip, mac); let mut ip_address = IPAddress::new(); ip_address.set_address(to_ip.to_string()); diff --git a/tools/packaging/kernel/configs/fragments/x86_64/tdx/tdx.conf b/tools/packaging/kernel/configs/fragments/x86_64/tdx/tdx.conf index a363ec6b6e..1b1f8751ef 100644 --- a/tools/packaging/kernel/configs/fragments/x86_64/tdx/tdx.conf +++ b/tools/packaging/kernel/configs/fragments/x86_64/tdx/tdx.conf @@ -1,13 +1,17 @@ # Intel Trust Domain Extensions (Intel TDX) +CONFIG_CLK_LGM_CGU=y +CONFIG_DMA_RESTRICTED_POOL=y CONFIG_EFI=y CONFIG_EFI_STUB=y -CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS=y -CONFIG_INTEL_TDX_GUEST=y +CONFIG_INTEL_IOMMU_SVM=y +CONFIG_INTEL_TDX_ATTESTATION=y CONFIG_INTEL_TDX_FIXES=y -CONFIG_X86_MEM_ENCRYPT_COMMON=y -CONFIG_X86_5LEVEL=y +CONFIG_INTEL_TDX_GUEST=y CONFIG_OF=y -CONFIG_CLK_LGM_CGU=y CONFIG_OF_RESERVED_MEM=y -CONFIG_DMA_RESTRICTED_POOL=y +CONFIG_X86_5LEVEL=y +CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS=y +CONFIG_X86_MEM_ENCRYPT_COMMON=y +CONFIG_X86_PLATFORM_DEVICES=y +CONFIG_X86_PLATFORM_DRIVERS_INTEL=y diff --git a/tools/packaging/kernel/kata_config_version b/tools/packaging/kernel/kata_config_version index c67f579c9a..49541f7210 100644 --- a/tools/packaging/kernel/kata_config_version +++ b/tools/packaging/kernel/kata_config_version @@ -1 +1 @@ -93 +94 diff --git a/tools/packaging/static-build/ovmf/Dockerfile b/tools/packaging/static-build/ovmf/Dockerfile index cffeb2ffb2..a9a148a756 100644 --- a/tools/packaging/static-build/ovmf/Dockerfile +++ b/tools/packaging/static-build/ovmf/Dockerfile @@ -17,5 +17,6 @@ RUN apt-get update && \ nasm \ python \ python3 \ + python3-distutils \ uuid-dev && \ apt-get clean && rm -rf /var/lib/lists/ diff --git a/tools/packaging/static-build/ovmf/build-ovmf.sh b/tools/packaging/static-build/ovmf/build-ovmf.sh index 83537686c9..9245dead48 100755 --- a/tools/packaging/static-build/ovmf/build-ovmf.sh +++ b/tools/packaging/static-build/ovmf/build-ovmf.sh @@ -1,6 +1,7 @@ #!/bin/bash # # Copyright (c) 2022 IBM +# Copyright (c) 2022 Intel # # SPDX-License-Identifier: Apache-2.0 @@ -15,7 +16,6 @@ source "${script_dir}/../../scripts/lib.sh" set +u ovmf_build="${ovmf_build:-x86_64}" ovmf_repo="${ovmf_repo:-}" -ovmf_dir="edk2" ovmf_version="${ovmf_version:-}" ovmf_package="${ovmf_package:-}" package_output_dir="${package_output_dir:-}" @@ -30,13 +30,14 @@ build_target="${build_target:-RELEASE}" [ -n "$ovmf_package" ] || die "failed to get ovmf package or commit" [ -n "$package_output_dir" ] || die "failed to get ovmf package or commit" +ovmf_dir="${ovmf_repo##*/}" + info "Build ${ovmf_repo} version: ${ovmf_version}" build_root=$(mktemp -d) pushd $build_root -git clone "${ovmf_repo}" +git clone --single-branch --depth 1 -b "${ovmf_version}" "${ovmf_repo}" cd "${ovmf_dir}" -git checkout "${ovmf_version}" git submodule init git submodule update @@ -53,16 +54,44 @@ if [ "${ovmf_build}" == "sev" ]; then fi info "Building ovmf" -build -b "${build_target}" -t "${toolchain}" -a "${architecture}" -p "${ovmf_package}" +build_cmd="build -b ${build_target} -t ${toolchain} -a ${architecture} -p ${ovmf_package}" +if [ "${ovmf_build}" == "tdx" ]; then + build_cmd+=" -D DEBUG_ON_SERIAL_PORT=TRUE -D TDX_MEM_PARTIAL_ACCEPT=512 -D TDX_EMULATION_ENABLE=FALSE -D TDX_ACCEPT_PAGE_SIZE=2M" +fi + +eval "${build_cmd}" info "Done Building" -build_path="Build/${package_output_dir}/${build_target}_${toolchain}/FV/OVMF.fd" -stat "${build_path}" +build_path_target_toolchain="Build/${package_output_dir}/${build_target}_${toolchain}" +build_path_fv="${build_path_target_toolchain}/FV" +stat "${build_path_fv}/OVMF.fd" +if [ "${ovmf_build}" == "tdx" ]; then + build_path_arch="${build_path_target_toolchain}/X64" + stat "${build_path_fv}/OVMF_CODE.fd" + stat "${build_path_fv}/OVMF_VARS.fd" + stat "${build_path_arch}/DumpTdxEventLog.efi" +fi #need to leave tmp dir popd info "Install fd to destdir" -mkdir -p "$DESTDIR/$PREFIX/share/ovmf" -cp $build_root/$ovmf_dir/"${build_path}" "$DESTDIR/$PREFIX/share/ovmf" \ No newline at end of file +install_dir="${DESTDIR}/${PREFIX}/share/ovmf" +if [ "${ovmf_build}" == "tdx" ]; then + install_dir="$DESTDIR/$PREFIX/share/tdvf" +fi + +mkdir -p "${install_dir}" +install $build_root/$ovmf_dir/"${build_path_fv}"/OVMF.fd "${install_dir}" +if [ "${ovmf_build}" == "tdx" ]; then + install $build_root/$ovmf_dir/"${build_path_fv}"/OVMF_CODE.fd ${install_dir} + install $build_root/$ovmf_dir/"${build_path_fv}"/OVMF_VARS.fd ${install_dir} + install $build_root/$ovmf_dir/"${build_path_arch}"/DumpTdxEventLog.efi ${install_dir} +fi + +local_dir=${PWD} +pushd $DESTDIR +tar -czvf "${local_dir}/${ovmf_dir}-${ovmf_build}.tar.gz" "./$PREFIX" +rm -rf $(dirname ./$PREFIX) +popd diff --git a/tools/packaging/static-build/ovmf/build.sh b/tools/packaging/static-build/ovmf/build.sh index 0662d20b82..fcbbd93210 100755 --- a/tools/packaging/static-build/ovmf/build.sh +++ b/tools/packaging/static-build/ovmf/build.sh @@ -25,7 +25,11 @@ ovmf_package="${ovmf_package:-}" package_output_dir="${package_output_dir:-}" if [ -z "$ovmf_repo" ]; then - ovmf_repo=$(get_from_kata_deps "externals.ovmf.url" "${kata_version}") + if [ "${ovmf_build}" == "tdx" ]; then + ovmf_repo=$(get_from_kata_deps "externals.ovmf.tdx.url" "${kata_version}") + else + ovmf_repo=$(get_from_kata_deps "externals.ovmf.url" "${kata_version}") + fi fi [ -n "$ovmf_repo" ] || die "failed to get ovmf repo" @@ -38,6 +42,10 @@ elif [ "${ovmf_build}" == "sev" ]; then [ -n "$ovmf_version" ] || ovmf_version=$(get_from_kata_deps "externals.ovmf.sev.version" "${kata_version}") [ -n "$ovmf_package" ] || ovmf_package=$(get_from_kata_deps "externals.ovmf.sev.package" "${kata_version}") [ -n "$package_output_dir" ] || package_output_dir=$(get_from_kata_deps "externals.ovmf.sev.package_output_dir" "${kata_version}") +elif [ "${ovmf_build}" == "tdx" ]; then + [ -n "$ovmf_version" ] || ovmf_version=$(get_from_kata_deps "externals.ovmf.tdx.version" "${kata_version}") + [ -n "$ovmf_package" ] || ovmf_package=$(get_from_kata_deps "externals.ovmf.tdx.package" "${kata_version}") + [ -n "$package_output_dir" ] || package_output_dir=$(get_from_kata_deps "externals.ovmf.tdx.package_output_dir" "${kata_version}") fi [ -n "$ovmf_version" ] || die "failed to get ovmf version or commit" diff --git a/tools/packaging/static-build/td-shim/build-td-shim.sh b/tools/packaging/static-build/td-shim/build-td-shim.sh index ed933c007e..cbc336d666 100755 --- a/tools/packaging/static-build/td-shim/build-td-shim.sh +++ b/tools/packaging/static-build/td-shim/build-td-shim.sh @@ -35,7 +35,8 @@ install target/x86_64-unknown-uefi/release/final-boot-kernel.bin ${install_dir}/ popd #td-shim popd #${build_root} +local_dir=${PWD} pushd ${DESTDIR} -tar -czvf "td-shim.tar.gz" "./$PREFIX" +tar -czvf "${local_dir}/td-shim.tar.gz" "./$PREFIX" rm -rf $(dirname ./$PREFIX) popd #${DESTDIR} diff --git a/versions.yaml b/versions.yaml index 181d1afe5f..993db9d853 100644 --- a/versions.yaml +++ b/versions.yaml @@ -101,7 +101,7 @@ assets: tdx: description: "VMM that uses KVM and supports TDX" url: "https://github.com/intel/qemu-dcp" - tag: "SPR-BKC-QEMU-v2.2" + tag: "SPR-BKC-QEMU-v2.5" qemu-experimental: description: "QEMU with virtiofs support" @@ -156,8 +156,8 @@ assets: version: "v5.15.48" tdx: description: "Linux kernel that supports TDX" - url: "https://github.com/intel/tdx/archive/refs/tags" - tag: "tdx-guest-v5.15-4" + url: "https://github.com/intel/linux-kernel-dcp/archive/refs/tags" + tag: "SPR-BKC-PC-v9.6" sev: description: "Linux kernel with efi_secret support" url: "https://github.com/confidential-containers-demo/\ @@ -261,6 +261,12 @@ externals: version: "edk2-stable202202" package: "OvmfPkg/AmdSev/AmdSevX64.dsc" package_output_dir: "AmdSev" + tdx: + url: "https://github.com/tianocore/edk2-staging" + description: "TDVF build needed for TDX measured direct boot." + version: "2022-tdvf-ww28.5" + package: "OvmfPkg/OvmfPkgX64.dsc" + package_output_dir: "OvmfX64" td-shim: description: "Confidential Containers Shim Firmware"