From bfb5ec7d033eaba7d86ab6d28f359fb8009427fe Mon Sep 17 00:00:00 2001 From: Daniel Zatovic Date: Wed, 5 Feb 2025 17:34:12 +0100 Subject: [PATCH] eclass/coreos-kernel,sys-kernel/coreos-modules: Move module signing key to /tmp, so that it stays in RAM. Disable shredding signing key after coreos-modules finishes, but rather shred it after coreos-kernel finishes, so that out of tree modules (like ZFS from upstream portage) can also use the key before it is shreded. --- .../eclass/coreos-kernel.eclass | 58 +++++++++++++------ .../profiles/coreos/base/make.defaults | 7 +++ .../coreos-kernel-6.6.88-r1.ebuild | 4 +- .../coreos-modules-6.6.88-r1.ebuild | 3 +- .../coreos-modules/files/commonconfig-6.6 | 2 +- sdk_lib/sdk_entry.sh | 14 +++++ 6 files changed, 64 insertions(+), 24 deletions(-) diff --git a/sdk_container/src/third_party/coreos-overlay/eclass/coreos-kernel.eclass b/sdk_container/src/third_party/coreos-overlay/eclass/coreos-kernel.eclass index d5f1346637..73b2a8b5ca 100644 --- a/sdk_container/src/third_party/coreos-overlay/eclass/coreos-kernel.eclass +++ b/sdk_container/src/third_party/coreos-overlay/eclass/coreos-kernel.eclass @@ -136,20 +136,41 @@ getconfig() { echo "${value}" } -# Generate the module signing key for this build. -setup_keys() { - local sig_hash sig_key - sig_hash=$(getconfig MODULE_SIG_HASH) - sig_key="build/$(getconfig MODULE_SIG_KEY)" +get_sig_key() { + local sig_key="$(getconfig MODULE_SIG_KEY)" if [[ "${sig_key}" == "build/certs/signing_key.pem" ]]; then die "MODULE_SIG_KEY is using the default value" fi - mkdir -p certs "${sig_key%/*}" || die + if [[ ${sig_key} != /tmp/* ]]; then + die "Refusing to to continue with modules key outside of /tmp, so that it stays in RAM only." + fi + if [ "$sig_key" != "${MODULES_SIGN_KEY}" ]; then + die "MODULES_SIGN_KEY variable is different than MODULE_SIG_KEY in kernel config." + fi + echo $sig_key +} + +validate_sig_key() { + get_sig_key > /dev/null +} + +# Generate the module signing key for this build. +setup_keys() { + local sig_hash sig_key + sig_hash=$(getconfig MODULE_SIG_HASH) + sig_key="$(get_sig_key)" + + echo "Preparing keys at $sig_key" + + mkdir -p $MODULE_SIGNING_KEY_DIR + pushd $MODULE_SIGNING_KEY_DIR + + mkdir -p gen_certs || die # based on the default config the kernel auto-generates - cat >certs/modules.cnf <<-EOF + cat >gen_certs/modules.cnf <<-EOF [ req ] default_bits = 4096 distinguished_name = req_distinguished_name @@ -169,19 +190,20 @@ setup_keys() { EOF openssl req -new -nodes -utf8 -days 36500 -batch -x509 \ "-${sig_hash}" -outform PEM \ - -config certs/modules.cnf \ - -out certs/modules.pub.pem \ - -keyout certs/modules.key.pem \ + -config gen_certs/modules.cnf \ + -out gen_certs/modules.pub.pem \ + -keyout gen_certs/modules.key.pem \ || die "Generating module signing key failed" - cat certs/modules.pub.pem certs/modules.key.pem > "${sig_key}" -} -# Discard the module signing key but keep public certificate. -shred_keys() { - local sig_key - sig_key="build/$(getconfig MODULE_SIG_KEY)" - shred -u certs/modules.key.pem "${sig_key}" || die - cp certs/modules.pub.pem "${sig_key}" || die + # copy the cert/key to desired location + mkdir -p "${MODULES_SIGN_CERT%/*}" "${MODULES_SIGN_KEY%/*}" || die + cat gen_certs/modules.pub.pem gen_certs/modules.key.pem > "$MODULES_SIGN_KEY" || die + cp gen_certs/modules.pub.pem $MODULES_SIGN_CERT || die + + shred -u gen_certs/* || die + rmdir gen_certs || die + + popd } # Populate /lib/modules/$(uname -r)/{build,source} diff --git a/sdk_container/src/third_party/coreos-overlay/profiles/coreos/base/make.defaults b/sdk_container/src/third_party/coreos-overlay/profiles/coreos/base/make.defaults index d4c756449a..3dfd7f2607 100644 --- a/sdk_container/src/third_party/coreos-overlay/profiles/coreos/base/make.defaults +++ b/sdk_container/src/third_party/coreos-overlay/profiles/coreos/base/make.defaults @@ -124,3 +124,10 @@ CGO_ENABLED=1 # Keep using old binary format for now. BINPKG_FORMAT=xpak + +# move signing key and cert to /tmp so that the ephemeral key is not stored on a disk +MODULES_SIGN_KEY="/tmp/certs/modules.pem" +MODULES_SIGN_CERT="/tmp/certs/modules.pub.pem" + +# enable signing kernel modules from portage +USE="${USE} modules-sign" diff --git a/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-kernel/coreos-kernel-6.6.88-r1.ebuild b/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-kernel/coreos-kernel-6.6.88-r1.ebuild index 7037847738..a8b19410cb 100644 --- a/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-kernel/coreos-kernel-6.6.88-r1.ebuild +++ b/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-kernel/coreos-kernel-6.6.88-r1.ebuild @@ -59,9 +59,7 @@ src_prepare() { # Pull in the config and public module signing key KV_OUT_DIR="${ESYSROOT}/lib/modules/${COREOS_SOURCE_NAME#linux-}/build" cp -v "${KV_OUT_DIR}/.config" build/ || die - local sig_key="$(getconfig MODULE_SIG_KEY)" - mkdir -p "build/${sig_key%/*}" || die - cp -v "${KV_OUT_DIR}/${sig_key}" "build/${sig_key}" || die + validate_sig_key config_update 'CONFIG_INITRAMFS_SOURCE="bootengine.cpio"' diff --git a/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-modules/coreos-modules-6.6.88-r1.ebuild b/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-modules/coreos-modules-6.6.88-r1.ebuild index 73c33b970e..88f3f5b596 100644 --- a/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-modules/coreos-modules-6.6.88-r1.ebuild +++ b/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-modules/coreos-modules-6.6.88-r1.ebuild @@ -16,7 +16,7 @@ src_prepare() { local archconfig="$(find_archconfig)" local commonconfig="$(find_commonconfig)" elog "Building using config ${archconfig} and ${commonconfig}" - cat "${archconfig}" "${commonconfig}" >> build/.config || die + cat "${archconfig}" "${commonconfig}" | envsubst '$MODULE_SIGNING_KEY_DIR' >> build/.config || die fi cpio -ov build/bootengine.cpio @@ -52,7 +52,6 @@ src_install() { rm "${D}/usr/lib/debug/usr/lib/modules/${KV_FULL}/build" || die # Clean up the build tree - shred_keys kmake clean # TODO: ensure that fixdep and kbuild tools shipped inside the image diff --git a/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-modules/files/commonconfig-6.6 b/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-modules/files/commonconfig-6.6 index bb489aafe2..f16f1fdd31 100644 --- a/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-modules/files/commonconfig-6.6 +++ b/sdk_container/src/third_party/coreos-overlay/sys-kernel/coreos-modules/files/commonconfig-6.6 @@ -498,7 +498,7 @@ CONFIG_MMC_SDHCI_PCI=m CONFIG_MODULES=y CONFIG_MODULE_COMPRESS_XZ=y CONFIG_MODULE_SIG=y -CONFIG_MODULE_SIG_KEY="certs/modules.pem" +CONFIG_MODULE_SIG_KEY="${MODULE_SIGNING_KEY_DIR}/certs/modules.pem" CONFIG_MODULE_SIG_SHA256=y CONFIG_MODULE_UNLOAD=y CONFIG_MOUSE_PS2=m diff --git a/sdk_lib/sdk_entry.sh b/sdk_lib/sdk_entry.sh index 9ebc141771..3c7aaeb356 100755 --- a/sdk_lib/sdk_entry.sh +++ b/sdk_lib/sdk_entry.sh @@ -49,6 +49,20 @@ sed -i -r '/^masters =/s/\bcoreos(\s|$)/coreos-overlay\1/g' /usr/local/portage/c fi ) +# SDK container is launched using the su command below, which does not preserve environment +# 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 +grep -q 'export MODULE_SIGNING_KEY_DIR' /home/sdk/.bashrc || { + MODULE_SIGNING_KEY_DIR=$(su sdk -c "mktemp -d") + if [[ ! "$MODULE_SIGNING_KEY_DIR" || ! -d "$MODULE_SIGNING_KEY_DIR" ]]; then + echo "Failed to create temporary directory for secure boot keys." + else + 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_CERT='${MODULE_SIGNING_KEY_DIR}/certs/modules.pub.pem'" >> /home/sdk/.bashrc + fi +} + # This is ugly. # We need to sudo su - sdk -c so the SDK user gets a fresh login. # 'sdk' is member of multiple groups, and plain docker USER only