Skip to content

Commit c56f7ca

Browse files
committed
sysext: Sign built-in sysexts
Generate an ephemeral sysext signing key, that is injected into the image's sysext root of trust. All OS-dependent sysexts will be signed by this key and the private key (stored in /tmp) will be discarded on SDK container exit.
1 parent 8d84cfe commit c56f7ca

File tree

5 files changed

+66
-12
lines changed

5 files changed

+66
-12
lines changed

build_library/prod_image_util.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,10 @@ EOF
164164
# Remove source locale data, only need to ship the compiled archive.
165165
sudo rm -rf ${root_fs_dir}/usr/share/i18n/
166166

167+
# Inject ephemeral sysext signing certificate
168+
sudo mkdir -p "${root_fs_dir}/usr/lib/verity.d"
169+
sudo cp "${SYSEXT_SIGNING_KEY_DIR}/sysexts.crt" "${root_fs_dir}/usr/lib/verity.d"
170+
167171
# Finish image will move files from /etc to /usr/share/flatcar/etc.
168172
# Note that image filesystem contents generated by finish_image will not
169173
# include sysext contents (only the sysext squashfs files themselves).

build_library/sysext_prod_builder

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ create_prod_sysext() {
6363
# The --install_root_basename="${name}-base-sysext-rootfs" flag is
6464
# important - it sets the name of a rootfs directory, which is used
6565
# to determine the package target in coreos/base/profile.bashrc
66-
sudo "FLATCAR_BUILD_ID=$FLATCAR_BUILD_ID" "${SCRIPTS_DIR}/build_sysext" \
66+
sudo -E "FLATCAR_BUILD_ID=$FLATCAR_BUILD_ID" "${SCRIPTS_DIR}/build_sysext" \
6767
--board="${BOARD}" \
6868
--image_builddir="${workdir}/sysext-build" \
6969
--squashfs_base="${base_sysext}" \
@@ -99,6 +99,14 @@ sysext_mountdir="${BUILD_DIR}/prod-sysext-work/mounts"
9999
sysext_base="${sysext_workdir}/base-os.squashfs"
100100

101101
function cleanup() {
102+
IFS=':' read -r -a mounted_sysexts <<< "$sysext_lowerdirs"
103+
# skip the rootfs
104+
mounted_sysexts=("${mounted_sysexts[@]:1}")
105+
106+
for sysext in "${mounted_sysexts[@]}"; do
107+
sudo systemd-dissect --umount --rmdir "$sysext"
108+
done
109+
102110
sudo umount "${sysext_mountdir}"/* || true
103111
rm -rf "${sysext_workdir}" || true
104112
}
@@ -116,6 +124,7 @@ sudo mksquashfs "${root_fs_dir}" "${sysext_base}" -noappend -xattrs-exclude '^bt
116124
# for combined overlay later.
117125
prev_pkginfo=""
118126
sysext_lowerdirs="${sysext_mountdir}/rootfs-lower"
127+
mkdir -p "${sysext_mountdir}"
119128
for sysext in ${sysexts_list//,/ }; do
120129
# format is "<name>:<group>/<package>"
121130
name="${sysext%|*}"
@@ -129,12 +138,21 @@ for sysext in ${sysexts_list//,/ }; do
129138
"${grp_pkg}" \
130139
"${prev_pkginfo}"
131140

132-
mkdir -p "${sysext_mountdir}/${name}" \
133-
"${sysext_mountdir}/${name}_pkginfo"
134-
sudo mount -rt squashfs -o loop,nodev "${sysext_output_dir}/${name}.raw" \
135-
"${sysext_mountdir}/${name}"
136-
sudo mount -rt squashfs -o loop,nodev "${sysext_output_dir}/${name}_pkginfo.raw" \
137-
"${sysext_mountdir}/${name}_pkginfo"
141+
sudo systemd-dissect \
142+
--read-only \
143+
--mount \
144+
--mkdir \
145+
--image-policy='root=encrypted+unprotected+absent:usr=encrypted+unprotected+absent' \
146+
"${sysext_output_dir}/${name}.raw" \
147+
"${sysext_mountdir}/${name}"
148+
149+
sudo systemd-dissect \
150+
--read-only \
151+
--mount \
152+
--mkdir \
153+
--image-policy='root=encrypted+unprotected+absent:usr=encrypted+unprotected+absent' \
154+
"${sysext_output_dir}/${name}_pkginfo.raw" \
155+
"${sysext_mountdir}/${name}_pkginfo"
138156

139157
sysext_lowerdirs="${sysext_lowerdirs}:${sysext_mountdir}/${name}"
140158
sysext_lowerdirs="${sysext_lowerdirs}:${sysext_mountdir}/${name}_pkginfo"

build_library/vm_image_util.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,7 @@ install_oem_sysext() {
591591
fi
592592

593593
mkdir -p "${built_sysext_dir}"
594-
sudo "${build_sysext_env[@]}" "${SCRIPT_ROOT}/build_sysext" "${build_sysext_flags[@]}" "${oem_sysext}"
594+
sudo -E "${build_sysext_env[@]}" "${SCRIPT_ROOT}/build_sysext" "${build_sysext_flags[@]}" "${oem_sysext}"
595595

596596
local installed_sysext_oem_dir='/oem/sysext'
597597
local installed_sysext_file_prefix="${oem_sysext}-${version}"

build_sysext

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -304,14 +304,25 @@ if [[ -n "${invalid_files}" ]]; then
304304
die "Invalid file ownership: ${invalid_files}"
305305
fi
306306

307-
mksquashfs "${BUILD_DIR}/${FLAGS_install_root_basename}" "${BUILD_DIR}/${SYSEXTNAME}.raw" \
308-
-noappend -xattrs-exclude '^btrfs.' -comp "${FLAGS_compression}" ${FLAGS_mksquashfs_opts}
307+
systemd-repart \
308+
--private-key="${SYSEXT_SIGNING_KEY_DIR}/sysexts.key" \
309+
--certificate="${SYSEXT_SIGNING_KEY_DIR}/sysexts.crt" \
310+
--make-ddi=sysext \
311+
--copy-source="${BUILD_DIR}/${FLAGS_install_root_basename}" \
312+
"${BUILD_DIR}/${SYSEXTNAME}.raw"
313+
309314
rm -rf "${BUILD_DIR}"/{fs-root,"${FLAGS_install_root_basename}",workdir}
310315

311316
# Generate reports
312317
mkdir "${BUILD_DIR}/img-rootfs"
313-
mount -rt squashfs -o loop,nodev "${BUILD_DIR}/${SYSEXTNAME}.raw" "${BUILD_DIR}/img-rootfs"
318+
systemd-dissect --read-only \
319+
--mount \
320+
--mkdir \
321+
--image-policy='root=encrypted+unprotected+absent:usr=encrypted+unprotected+absent' \
322+
"${BUILD_DIR}/${SYSEXTNAME}.raw" \
323+
"${BUILD_DIR}/img-rootfs"
324+
314325
write_contents "${BUILD_DIR}/img-rootfs" "${BUILD_DIR}/${SYSEXTNAME}_contents.txt"
315326
write_contents_with_technical_details "${BUILD_DIR}/img-rootfs" "${BUILD_DIR}/${SYSEXTNAME}_contents_wtd.txt"
316327
write_disk_space_usage_in_paths "${BUILD_DIR}/img-rootfs" "${BUILD_DIR}/${SYSEXTNAME}_disk_usage.txt"
317-
umount "${BUILD_DIR}/img-rootfs"
328+
systemd-dissect --umount --rmdir "${BUILD_DIR}/img-rootfs"

sdk_lib/sdk_entry.sh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,27 @@ grep -q 'export MODULE_SIGNING_KEY_DIR' /home/sdk/.bashrc || {
6363
fi
6464
}
6565

66+
grep -q 'export SYSEXT_SIGNING_KEY_DIR' /home/sdk/.bashrc || {
67+
SYSEXT_SIGNING_KEY_DIR=$(su sdk -c "mktemp -d")
68+
if [[ ! "$SYSEXT_SIGNING_KEY_DIR" || ! -d "$SYSEXT_SIGNING_KEY_DIR" ]]; then
69+
echo "Failed to create temporary directory for secure boot keys."
70+
else
71+
echo "export SYSEXT_SIGNING_KEY_DIR='$SYSEXT_SIGNING_KEY_DIR'" >> /home/sdk/.bashrc
72+
fi
73+
pushd "$SYSEXT_SIGNING_KEY_DIR"
74+
build_id=$(source "/mnt/host/source/.repo/manifests/version.txt"; echo "$FLATCAR_BUILD_ID")
75+
openssl req -new -nodes -utf8 \
76+
-x509 -batch -sha256 \
77+
-days 36000 \
78+
-outform PEM \
79+
-out sysexts.crt \
80+
-keyout sysexts.key \
81+
-newkey 4096 \
82+
-subj "/CN=Flatcar $build_id sysext signing key/" \
83+
|| echo "Generating module signing key failed"
84+
popd
85+
}
86+
6687
# This is ugly.
6788
# We need to sudo su - sdk -c so the SDK user gets a fresh login.
6889
# 'sdk' is member of multiple groups, and plain docker USER only

0 commit comments

Comments
 (0)