From 861ffc1097685f9ecf13adaa381aca5fdf7ef0b4 Mon Sep 17 00:00:00 2001 From: Samuel Karp Date: Mon, 8 Jun 2026 00:58:16 +0000 Subject: [PATCH] cri: filter CDI annotations on checkpoint restore Filter out any annotations on the checkpointed container matching `cdi.k8s.io/` or exactly `cdi.k8s.io` during restore to prevent unauthorized device restoration. When an annotation is denied, a warning log is generated. Tested by: * Unit tests for exact matching, prefix boundaries, and metadata merging * Complete CRI integration and checkpoint restore suite Assisted-by: Antigravity Signed-off-by: Samuel Karp --- .../checkpoint/checkpoint-restore-cri-test.sh | 22 +++- .../cri/server/container_checkpoint_linux.go | 56 ++++++--- .../server/container_checkpoint_linux_test.go | 107 ++++++++++++++++++ 3 files changed, 167 insertions(+), 18 deletions(-) create mode 100644 internal/cri/server/container_checkpoint_linux_test.go diff --git a/contrib/checkpoint/checkpoint-restore-cri-test.sh b/contrib/checkpoint/checkpoint-restore-cri-test.sh index 54735db14..82197fa76 100755 --- a/contrib/checkpoint/checkpoint-restore-cri-test.sh +++ b/contrib/checkpoint/checkpoint-restore-cri-test.sh @@ -56,6 +56,15 @@ TESTDATA=testdata # shellcheck disable=SC2034 export CONTAINERD_ADDRESS="$TESTDIR/c.sock" export CONTAINER_RUNTIME_ENDPOINT="unix:///${CONTAINERD_ADDRESS}" + +# Generate crictl config file with 30s timeout +export CRI_CONFIG_FILE="${TESTDIR}/crictl.yaml" +cat < "${CRI_CONFIG_FILE}" +runtime-endpoint: unix://${CONTAINERD_ADDRESS} +image-endpoint: unix://${CONTAINERD_ADDRESS} +timeout: 30 +EOF + TEST_IMAGE=ghcr.io/containerd/alpine function test_from_archive() { @@ -69,9 +78,12 @@ function test_from_archive() { echo -n "--> Start pod: " pod_id=$(crictl runp "$POD_JSON") echo "$pod_id" + CTR_JSON=$(mktemp) + jq '.annotations = {"cdi.k8s.io/device":"gpu","safe.annotation":"true"}' "$TESTDATA"/container_sleep.json >"$CTR_JSON" echo -n "--> Create container: " - ctr_id=$(crictl create "$pod_id" "$TESTDATA"/container_sleep.json "$POD_JSON") + ctr_id=$(crictl create "$pod_id" "$CTR_JSON" "$POD_JSON") echo "$ctr_id" + rm -f "$CTR_JSON" echo -n "--> Start container: " crictl start "$ctr_id" lines_before=$(crictl logs "$ctr_id" | wc -l) @@ -108,6 +120,12 @@ function test_from_archive() { "should be larger than before checkpointing ($lines_before)" false fi + echo "--> Verifying CDI annotation filtering on restore: " + actual_annots=$(crictl inspect "$ctr_id" | jq -c '.status.annotations') + if jq -e 'has("cdi.k8s.io/device") or (has("safe.annotation") | not)' <<<"$actual_annots" >/dev/null; then + echo "error: CDI annotation was not filtered or safe annotation missing: $actual_annots" + exit 1 + fi # Cleanup echo "--> Cleanup images: " crictl rmi "${TEST_IMAGE}" | sed 's/^/----> \t/' @@ -192,6 +210,8 @@ function test_from_oci() { cat >"${TESTDIR}/config.toml" <