Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Secret hiding base CI resource #5096

Merged
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
9 changes: 9 additions & 0 deletions .buildkite/pipeline_pr.py
Original file line number Diff line number Diff line change
@@ -68,6 +68,15 @@
for step in kani_grp["steps"]:
step["label"] = "🔍 Kani"

if any(x.parent.name == "hiding_ci" for x in changed_files):
pipeline.build_group_per_arch(
"🕵️ Build Secret Hiding Kernel",
pipeline.devtool_test(
pytest_opts="-m secret_hiding integration_tests/build/test_hiding_kernel.py",
),
depends_on_build=False,
)

if run_all_tests(changed_files):
pipeline.build_group(
"📦 Build",
170 changes: 170 additions & 0 deletions resources/hiding_ci/build_and_install_kernel.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
#!/bin/bash
# Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

# fail if we encounter an error, uninitialized variable or a pipe breaks
set -eu -o pipefail

check_root() {
# We need sudo privileges to install the kernel
if [ "$(id -u)" -ne 0 ]; then
echo "To install, this script must be run as root or with sudo privileges"
exit 1
fi
}

check_ubuntu() {
# Currently this script only works on Ubuntu instances
if ! grep -qi 'ubuntu' /etc/os-release; then
echo "This script currently only works on Ubuntu."
exit 1
fi
}

tidy_up() {
# Some cleanup after we are done
echo "Cleaning up.."
popd
rm -rf $TMP_BUILD_DIR
}

confirm() {
if [[ "$*" == *"--no-install"* ]]; then
echo "Not installing new kernel."

if [[ "$*" == *"--tidy"* ]]; then
tidy_up
fi

exit 0
fi

if [[ "$*" == *"--install"* ]]; then
return 0
fi

while true; do
read -p "Do you want to install the new kernel? (y/n) " yn
case $yn in
[Yy]*) return 0 ;;
[Nn]*)
echo "Exiting..."
exit 1
;;
*) echo "Please answer yes or no." ;;
esac
done
}

apply_patch_file() {
git apply $1
}

apply_series_mbox() {
git am $1 --empty=drop
}

apply_series_link() {
patch_url=$(cat $1)
echo "Fetching mbox from:" $patch_url
curl --output lore.mbox.gz "$patch_url/t.mbox.gz"
gunzip lore.mbox
apply_series_mbox lore.mbox
rm lore.mbox
}

apply_patch_or_series() {
case "$1" in
*.patch) apply_patch_file $1 ;;
*.mbox) apply_series_mbox $1 ;;
*.lore) apply_series_link $1 ;;
*)
echo "Uknown patch file: "$1
exit 1
;;
esac
}

check_override_presence() {
while IFS= read -r line; do
if ! grep -Fq "$line" .config; then
echo "Missing config: $line"
exit 1
fi
done <"$KERNEL_CONFIG_OVERRIDES"

echo "All overrides correctly applied.."
}

KERNEL_URL=$(cat kernel_url)
KERNEL_COMMIT_HASH=$(cat kernel_commit_hash)
KERNEL_PATCHES_DIR=$(pwd)/patches
KERNEL_CONFIG_OVERRIDES=$(pwd)/kernel_config_overrides

TMP_BUILD_DIR=$(mktemp -d -t kernel-build-XXXX)

pushd .
cd $TMP_BUILD_DIR

echo "Cloning kernel repository into" $TMP_BUILD_DIR

# We checkout the repository that way to make it as
# small and fast as possible
git init
git remote add origin $KERNEL_URL
git fetch --depth 1 origin $KERNEL_COMMIT_HASH
git checkout FETCH_HEAD

# Apply our patches on top
for PATCH in $KERNEL_PATCHES_DIR/*.*; do
echo "Applying patch:" $(basename $PATCH)
apply_patch_or_series $PATCH
done

echo "Making kernel config ready for build"
# We use olddefconfig to automatically pull in the
# config from the AMI and update to the newest
# defaults
make olddefconfig

# Disable the ubuntu keys
scripts/config --disable SYSTEM_TRUSTED_KEYS
scripts/config --disable SYSTEM_REVOCATION_KEYS

# We run this again to default options now changed by
# the disabling of the ubuntu keys
make olddefconfig

# Apply our config overrides on top of the config
scripts/kconfig/merge_config.sh -m .config $KERNEL_CONFIG_OVERRIDES

check_override_presence

echo "Building kernel this may take a while"
make -s -j $(nproc)
echo "Building kernel modules"
make modules -s -j $(nproc)
echo "Kernel build complete!"

KERNEL_VERSION=$(KERNELVERSION=$(make -s kernelversion) ./scripts/setlocalversion)

echo "New kernel version:" $KERNEL_VERSION

# Make sure a user really wants to install this kernel
confirm "$@"

check_root
check_ubuntu

echo "Installing kernel modules..."
make INSTALL_MOD_STRIP=1 modules_install
echo "Installing kernel..."
make INSTALL_MOD_STRIP=1 install
echo "Update initramfs"
update-initramfs -c -k $KERNEL_VERSION
echo "Updating GRUB..."
update-grub

echo "Kernel built and installed successfully!"

tidy_up
1 change: 1 addition & 0 deletions resources/hiding_ci/kernel_commit_hash
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
4701f33a10702d5fc577c32434eb62adde0a1ae1
6 changes: 6 additions & 0 deletions resources/hiding_ci/kernel_config_overrides
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
CONFIG_EXPERT=y
CONFIG_KVM=y
CONFIG_KVM_SW_PROTECTED_VM=y
CONFIG_KVM_PRIVATE_MEM=y
CONFIG_KVM_AMD_SEV=y
CONFIG_DEBUG_INFO=y
1 change: 1 addition & 0 deletions resources/hiding_ci/kernel_url
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
git://git.kernel.org/pub/scm/virt/kvm/kvm.git
1 change: 1 addition & 0 deletions resources/hiding_ci/patches/0001.lore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
https://lore.kernel.org/kvm/20250318161823.4005529-1-tabba@google.com
2 changes: 2 additions & 0 deletions tests/README.md
Original file line number Diff line number Diff line change
@@ -340,6 +340,8 @@ which tests are run in which context:
in separate pipelines according to various cron schedules.
- Tests marked as `no_block_pr` are run in the "optional" PR CI pipeline. This
pipeline is not required to pass for merging a PR.
- Tests marked as `secret_hiding` are secret hiding specifc tests. They don't
run by default.

All tests without markers are run for every pull request, and are required to
pass for the PR to be merged.
29 changes: 29 additions & 0 deletions tests/integration_tests/build/test_hiding_kernel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
"""A test which checks that the secret hiding enable kernel builds successfully."""

import pytest

from framework import utils


@pytest.mark.timeout(600)
@pytest.mark.secret_hiding
def test_build_hiding_kernel():
"""
In the test we will run our kernel build script to check it succeeds and builds the hidden kernel
"""

# We have some extra deps for building the kernel that are not in the dev contaner
utils.check_output(
"apt install -y build-essential libncurses-dev bison flex libssl-dev libelf-dev bc dwarves libncurses5-dev kmod fakeroot"
)

# We have to configure git otherwise patch application fails
# the git log still credits the original author
utils.check_output('git config --global user.name "Firecracker CI"')
utils.check_output('git config --global user.email "ci@email.com"')

utils.check_output(
"cd ../resources/hiding_ci; ./build_and_install_kernel.sh --no-install --tidy"
)
3 changes: 2 additions & 1 deletion tests/pytest.ini
Original file line number Diff line number Diff line change
@@ -5,12 +5,13 @@ addopts =
-vv
--durations=10
--showlocals
-m 'not nonci and not no_block_pr'
-m 'not nonci and not no_block_pr and not secret_hiding'
--json-report --json-report-file=../test_results/test-report.json

markers =
no_block_pr: tests whose failure does not block PR merging.
nonci: mark test as nonci.
secret_hiding: tests related to secret hiding.

; Overwrite the default norecursedirs, which includes 'build'.
norecursedirs = .*