Fix kernel module signing with ephemeral keys for official builds (#3493)

* sdk: Fix ephemeral key directory paths baked into container images

The SDK container build process was persisting temporary directory
paths for module signing keys into /home/sdk/.bashrc. This caused
all container instances to share the same ephemeral key location.

Fixed by:
- Runtime check in sdk_entry.sh to recreate stale temp directories
- Build-time cleanup in Dockerfiles to remove the variables

Each container instance now gets unique temporary directories.

Signed-off-by: Daniel Zatovic <daniel.zatovic@gmail.com>

* sdk_entry: use persistent module signing keys for unofficial builds

For official builds (COREOS_OFFICIAL=1), continue using ephemeral
temporary directories for module signing keys.

For unofficial/development builds, use a persistent directory at
/mnt/host/source/.module-signing-keys to preserve keys across
container restarts.

Signed-off-by: Daniel Zatovic <daniel.zatovic@gmail.com>

---------

Signed-off-by: Daniel Zatovic <daniel.zatovic@gmail.com>
This commit is contained in:
Daniel 2025-11-20 09:56:49 +01:00 committed by GitHub
parent 72a74fdce7
commit f05097d82f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 60 additions and 10 deletions

View File

@ -143,14 +143,18 @@ get_sig_key() {
die "MODULE_SIG_KEY is using the default value" die "MODULE_SIG_KEY is using the default value"
fi fi
if [[ ${sig_key} != /tmp/* ]]; then # For official builds, enforce /tmp to keep keys in RAM only
die "Refusing to to continue with modules key outside of /tmp, so that it stays in RAM only." # For unofficial builds, allow persistent directory
if [[ ${COREOS_OFFICIAL:-0} -eq 1 ]]; then
if [[ ${sig_key} != /tmp/* ]]; then
die "Refusing to continue with modules key outside of /tmp for official builds, so that it stays in RAM only."
fi
fi fi
if [ "$sig_key" != "${MODULES_SIGN_KEY}" ]; then if [ "$sig_key" != "${MODULES_SIGN_KEY}" ]; then
die "MODULES_SIGN_KEY variable is different than MODULE_SIG_KEY in kernel config." die "MODULES_SIGN_KEY variable is different than MODULE_SIG_KEY in kernel config."
fi fi
echo $sig_key echo "$sig_key"
} }
validate_sig_key() { validate_sig_key() {
@ -165,8 +169,14 @@ setup_keys() {
echo "Preparing keys at $sig_key" echo "Preparing keys at $sig_key"
mkdir -p $MODULE_SIGNING_KEY_DIR if [[ ${COREOS_OFFICIAL:-0} -eq 0 ]]; then
pushd $MODULE_SIGNING_KEY_DIR # Allow portage sandbox to write to the module signing key directory,
# which is in home for unofficial builds
addwrite "${MODULE_SIGNING_KEY_DIR}"
fi
mkdir -p "$MODULE_SIGNING_KEY_DIR"
pushd "$MODULE_SIGNING_KEY_DIR"
mkdir -p gen_certs || die mkdir -p gen_certs || die
# based on the default config the kernel auto-generates # based on the default config the kernel auto-generates

View File

@ -17,3 +17,8 @@ RUN /home/sdk/sdk_entry.sh ./build_packages --board="amd64-usr" --only_resolve_c
RUN rm /mnt/host/source/.env RUN rm /mnt/host/source/.env
RUN rm -rf /home/sdk/toolchain-pkgs RUN rm -rf /home/sdk/toolchain-pkgs
# Clean up ephemeral key directory variables that were added during build
RUN sed -i -e '/export MODULE_SIGNING_KEY_DIR=/d' \
-e '/export MODULES_SIGN_KEY=/d' \
-e '/export MODULES_SIGN_CERT=/d' /home/sdk/.bashrc

View File

@ -55,4 +55,9 @@ RUN chmod 755 /home/sdk/sdk_entry.sh
# it's likely that scripts and SDK tarball are out of sync # it's likely that scripts and SDK tarball are out of sync
RUN /home/sdk/sdk_entry.sh ./update_chroot --toolchain_boards="amd64-usr arm64-usr" RUN /home/sdk/sdk_entry.sh ./update_chroot --toolchain_boards="amd64-usr arm64-usr"
# Clean up ephemeral key directory variables that were added during build
RUN sed -i -e '/export MODULE_SIGNING_KEY_DIR=/d' \
-e '/export MODULES_SIGN_KEY=/d' \
-e '/export MODULES_SIGN_CERT=/d' /home/sdk/.bashrc
ENTRYPOINT ["/home/sdk/sdk_entry.sh"] ENTRYPOINT ["/home/sdk/sdk_entry.sh"]

View File

@ -19,3 +19,8 @@ RUN /home/sdk/sdk_entry.sh ./setup_board --board="amd64-usr" --regen_configs
# Restore original .bashrc to remove sandbox disablement # Restore original .bashrc to remove sandbox disablement
RUN mv /home/sdk/.bashrc.bak /home/sdk/.bashrc RUN mv /home/sdk/.bashrc.bak /home/sdk/.bashrc
RUN chown sdk:sdk /home/sdk/.bashrc RUN chown sdk:sdk /home/sdk/.bashrc
# Clean up ephemeral key directory variables that were added during build
RUN sed -i -e '/export MODULE_SIGNING_KEY_DIR=/d' \
-e '/export MODULES_SIGN_KEY=/d' \
-e '/export MODULES_SIGN_CERT=/d' /home/sdk/.bashrc

View File

@ -1,5 +1,10 @@
#!/bin/bash #!/bin/bash
# Source SDK environment variables if available (includes COREOS_OFFICIAL, etc.)
if [ -f /mnt/host/source/.sdkenv ]; then
source /mnt/host/source/.sdkenv
fi
if [ -n "${SDK_USER_ID:-}" ] ; then if [ -n "${SDK_USER_ID:-}" ] ; then
# If the "core" user from /usr/share/baselayout/passwd has the same ID, allow to take it instead # If the "core" user from /usr/share/baselayout/passwd has the same ID, allow to take it instead
usermod --non-unique -u $SDK_USER_ID sdk usermod --non-unique -u $SDK_USER_ID sdk
@ -52,16 +57,36 @@ sed -i -r '/^masters =/s/\bcoreos(\s|$)/coreos-overlay\1/g' /usr/local/portage/c
# SDK container is launched using the su command below, which does not preserve environment # SDK container is launched using the su command below, which does not preserve environment
# moreover, if multiple shells are attached to the same container, # moreover, if multiple shells are attached to the same container,
# we want all of them to share the same value of the variable, therefore we need to save it in .bashrc # we want all of them to share the same value of the variable, therefore we need to save it in .bashrc
grep -q 'export MODULE_SIGNING_KEY_DIR' /home/sdk/.bashrc || { # Check if MODULE_SIGNING_KEY_DIR exists in .bashrc and if the directory actually exists
MODULE_SIGNING_KEY_DIR=$(su sdk -c "mktemp -d") if grep -q 'export MODULE_SIGNING_KEY_DIR=' /home/sdk/.bashrc; then
if [[ ! "$MODULE_SIGNING_KEY_DIR" || ! -d "$MODULE_SIGNING_KEY_DIR" ]]; then # Extract the existing path
echo "Failed to create temporary directory for secure boot keys." EXISTING_DIR=$(source /home/sdk/.bashrc 2>/dev/null; echo "$MODULE_SIGNING_KEY_DIR")
# If directory doesn't exist (stale from image build), remove the old entries and recreate
if [[ ! -d ${EXISTING_DIR} ]]; then
echo "Deleting stale module signing directory."
sed -i -e '/export MODULE_SIGNING_KEY_DIR=/d' \
-e '/export MODULES_SIGN_KEY=/d' \
-e '/export MODULES_SIGN_CERT=/d' /home/sdk/.bashrc
fi
fi
# Create key directory if not already configured in .bashrc
if ! grep -q 'export MODULE_SIGNING_KEY_DIR=' /home/sdk/.bashrc; then
# For official builds, use ephemeral keys. For unofficial builds, use persistent directory
if [[ ${COREOS_OFFICIAL:-0} -eq 1 ]]; then
MODULE_SIGNING_KEY_DIR=$(su sdk -c "mktemp -d")
else
MODULE_SIGNING_KEY_DIR="/home/sdk/.module-signing-keys"
su sdk -c "mkdir -p ${MODULE_SIGNING_KEY_DIR@Q}"
fi
if [[ ! ${MODULE_SIGNING_KEY_DIR} || ! -d ${MODULE_SIGNING_KEY_DIR} ]]; then
echo "Failed to create directory for module signing keys."
else else
echo "export MODULE_SIGNING_KEY_DIR='$MODULE_SIGNING_KEY_DIR'" >> /home/sdk/.bashrc echo "export MODULE_SIGNING_KEY_DIR='$MODULE_SIGNING_KEY_DIR'" >> /home/sdk/.bashrc
echo "export MODULES_SIGN_KEY='${MODULE_SIGNING_KEY_DIR}/certs/modules.pem'" >> /home/sdk/.bashrc echo "export MODULES_SIGN_KEY='${MODULE_SIGNING_KEY_DIR}/certs/modules.pem'" >> /home/sdk/.bashrc
echo "export MODULES_SIGN_CERT='${MODULE_SIGNING_KEY_DIR}/certs/modules.pub.pem'" >> /home/sdk/.bashrc echo "export MODULES_SIGN_CERT='${MODULE_SIGNING_KEY_DIR}/certs/modules.pub.pem'" >> /home/sdk/.bashrc
fi fi
} fi
# This is ugly. # This is ugly.
# We need to sudo su - sdk -c so the SDK user gets a fresh login. # We need to sudo su - sdk -c so the SDK user gets a fresh login.