Merge pull request #421 from gtank/verity

dm-verity build support
This commit is contained in:
George Tankersley 2015-07-01 18:37:30 -07:00
commit 35b82cbaaf
5 changed files with 62 additions and 30 deletions

View File

@ -24,6 +24,8 @@ DEFINE_string board "${DEFAULT_BOARD}" \
"The board to build an image for." "The board to build an image for."
DEFINE_boolean enable_rootfs_verification ${FLAGS_TRUE} \ DEFINE_boolean enable_rootfs_verification ${FLAGS_TRUE} \
"Default all bootloaders to use kernel-based root fs integrity checking." "Default all bootloaders to use kernel-based root fs integrity checking."
DEFINE_boolean enable_verity ${FLAGS_FALSE} \
"Default GRUB to use dm-verity-enabled boot arguments"
DEFINE_string base_pkg "coreos-base/coreos" \ DEFINE_string base_pkg "coreos-base/coreos" \
"The base portage package to base the build off of (only applies to prod images)" "The base portage package to base the build off of (only applies to prod images)"
DEFINE_string base_dev_pkg "coreos-base/coreos-dev" \ DEFINE_string base_dev_pkg "coreos-base/coreos-dev" \

View File

@ -258,11 +258,11 @@ finish_image() {
local disk_img="${BUILD_DIR}/${image_name}" local disk_img="${BUILD_DIR}/${image_name}"
# Copy kernel to support dm-verity boots
sudo mkdir -p "${root_fs_dir}/boot/coreos" sudo mkdir -p "${root_fs_dir}/boot/coreos"
sudo cp "${root_fs_dir}/usr/boot/vmlinuz" \ sudo cp "${root_fs_dir}/usr/boot/vmlinuz" \
"${root_fs_dir}/boot/coreos/vmlinuz-a" "${root_fs_dir}/boot/coreos/vmlinuz-a"
sudo cp "${root_fs_dir}/usr/boot/vmlinuz" \
"${root_fs_dir}/boot/coreos/vmlinuz-b"
# Record directories installed to the state partition. # Record directories installed to the state partition.
# Explicitly ignore entries covered by existing configs. # Explicitly ignore entries covered by existing configs.
local tmp_ignore=$(awk '/^[dDfFL]/ {print "--ignore=" $2}' \ local tmp_ignore=$(awk '/^[dDfFL]/ {print "--ignore=" $2}' \
@ -303,19 +303,36 @@ finish_image() {
sudo chroot ${root_fs_dir} bash -c "cd /usr/share/selinux/mcs; semodule -i *.pp" sudo chroot ${root_fs_dir} bash -c "cd /usr/share/selinux/mcs; semodule -i *.pp"
fi fi
# Sign the kernels after /usr is in a consistent state # We only need to disable rw and apply dm-verity in prod with a /usr partition
if [ "${PROD_IMAGE}" -eq 1 ] && mountpoint -q "${root_fs_dir}/usr"; then
local disable_read_write=${FLAGS_enable_rootfs_verification}
# Unmount /usr partition
sudo umount --recursive "${root_fs_dir}/usr" || exit 1
# Make the filesystem un-mountable as read-write and setup verity.
if [[ ${disable_read_write} -eq ${FLAGS_TRUE} ]]; then
"${BUILD_LIBRARY_DIR}/disk_util" --disk_layout="${disk_layout}" verity \
--root_hash="${BUILD_DIR}/${image_name%.bin}_verity.txt" \
"${BUILD_DIR}/${image_name}"
# Magic alert! Root hash injection works by replacing a seldom-used rdev
# error message in the uncompressed section of the kernel that happens to
# be exactly SHA256-sized. Our modified GRUB extracts it to the cmdline.
printf %s "$(cat ${BUILD_DIR}/${image_name%.bin}_verity.txt)" | \
sudo dd of="${root_fs_dir}/boot/coreos/vmlinuz-a" conv=notrunc seek=64 count=64 bs=1
fi
fi
# Sign the kernel after /usr is in a consistent state and verity is calculated
if [[ ${COREOS_OFFICIAL:-0} -ne 1 ]]; then if [[ ${COREOS_OFFICIAL:-0} -ne 1 ]]; then
sudo sbsign --key /usr/share/sb_keys/DB.key \ sudo sbsign --key /usr/share/sb_keys/DB.key \
--cert /usr/share/sb_keys/DB.crt \ --cert /usr/share/sb_keys/DB.crt \
"${root_fs_dir}/boot/coreos/vmlinuz-a" "${root_fs_dir}/boot/coreos/vmlinuz-a"
sudo mv "${root_fs_dir}/boot/coreos/vmlinuz-a.signed" \ sudo mv "${root_fs_dir}/boot/coreos/vmlinuz-a.signed" \
"${root_fs_dir}/boot/coreos/vmlinuz-a" "${root_fs_dir}/boot/coreos/vmlinuz-a"
sudo sbsign --key /usr/share/sb_keys/DB.key \
--cert /usr/share/sb_keys/DB.crt \
"${root_fs_dir}/boot/coreos/vmlinuz-b"
sudo mv "${root_fs_dir}/boot/coreos/vmlinuz-b.signed" \
"${root_fs_dir}/boot/coreos/vmlinuz-b"
fi fi
rm -rf "${BUILD_DIR}"/configroot rm -rf "${BUILD_DIR}"/configroot
cleanup_mounts "${root_fs_dir}" cleanup_mounts "${root_fs_dir}"
trap - EXIT trap - EXIT
@ -324,8 +341,13 @@ finish_image() {
if [[ "${install_grub}" -eq 1 ]]; then if [[ "${install_grub}" -eq 1 ]]; then
local target local target
for target in i386-pc x86_64-efi x86_64-xen; do for target in i386-pc x86_64-efi x86_64-xen; do
${BUILD_LIBRARY_DIR}/grub_install.sh \ if [[ "${PROD_IMAGE}" -eq 1 && ${FLAGS_enable_verity} -eq ${FLAGS_TRUE} ]]; then
--target="${target}" --disk_image="${disk_img}" ${BUILD_LIBRARY_DIR}/grub_install.sh \
--target="${target}" --disk_image="${disk_img}" --verity
else
${BUILD_LIBRARY_DIR}/grub_install.sh \
--target="${target}" --disk_image="${disk_img}" --noverity
fi
done done
fi fi
} }

View File

@ -62,19 +62,19 @@ menuentry "CoreOS default" --id=coreos {
gptprio.next -d usr -u usr_uuid gptprio.next -d usr -u usr_uuid
if [ "$usr_uuid" = "7130c94a-213a-4e5a-8e26-6cce9662f132" ]; then if [ "$usr_uuid" = "7130c94a-213a-4e5a-8e26-6cce9662f132" ]; then
linux$suf /coreos/vmlinuz-a $linux_console $linux_root \ linux$suf /coreos/vmlinuz-a $linux_console $linux_root \
mount.usr=PARTUUID=$usr_uuid $linux_append @@MOUNTUSR@@=PARTUUID=$usr_uuid $linux_append
else else
linux$suf /coreos/vmlinuz-b $linux_console $linux_root \ linux$suf /coreos/vmlinuz-b $linux_console $linux_root \
mount.usr=PARTUUID=$usr_uuid $linux_append @@MOUNTUSR@@=PARTUUID=$usr_uuid $linux_append
fi fi
} }
menuentry "CoreOS USR-A" --id=coreos-a { menuentry "CoreOS USR-A" --id=coreos-a {
linux$suf /coreos/vmlinuz-a $linux_console $linux_root \ linux$suf /coreos/vmlinuz-a $linux_console $linux_root \
mount.usr=PARTLABEL=USR-A $linux_append @@MOUNTUSR@@=PARTLABEL=USR-A $linux_append
} }
menuentry "CoreOS USR-B" --id=coreos-b { menuentry "CoreOS USR-B" --id=coreos-b {
linux$suf /coreos/vmlinuz-b $linux_console $linux_root \ linux$suf /coreos/vmlinuz-b $linux_console $linux_root \
mount.usr=PARTLABEL=USR-B $linux_append @@MOUNTUSR@@=PARTLABEL=USR-B $linux_append
} }

View File

@ -20,6 +20,8 @@ DEFINE_string esp_dir "" \
"Path to EFI System partition mount point." "Path to EFI System partition mount point."
DEFINE_string disk_image "" \ DEFINE_string disk_image "" \
"The disk image containing the EFI System partition." "The disk image containing the EFI System partition."
DEFINE_boolean verity ${FLAGS_FALSE} \
"Indicates that boot commands should enable dm-verity."
# Parse flags # Parse flags
FLAGS "$@" || exit 1 FLAGS "$@" || exit 1
@ -71,6 +73,9 @@ cleanup() {
if [[ -b "${LOOP_DEV}" ]]; then if [[ -b "${LOOP_DEV}" ]]; then
sudo losetup --detach "${LOOP_DEV}" sudo losetup --detach "${LOOP_DEV}"
fi fi
if [[ -n "${GRUB_TEMP_DIR}" && -e "${GRUB_TEMP_DIR}" ]]; then
rm -r "${GRUB_TEMP_DIR}"
fi
} }
trap cleanup EXIT trap cleanup EXIT
@ -116,10 +121,26 @@ set prefix=(memdisk)
set set
EOF EOF
# Generate a memdisk containing the appropriately generated grub.cfg. Doing
# this because we need conflicting default behaviors between verity and
# non-verity images.
GRUB_TEMP_DIR=$(mktemp -d)
if [[ ! -f "${ESP_DIR}/coreos/grub/grub.cfg.tar" ]]; then if [[ ! -f "${ESP_DIR}/coreos/grub/grub.cfg.tar" ]]; then
info "Generating grub.cfg memdisk" info "Generating grub.cfg memdisk"
if [[ ${FLAGS_verity} -eq ${FLAGS_TRUE} ]]; then
# use dm-verity for /usr
cat "${BUILD_LIBRARY_DIR}/grub.cfg" | \
sed 's/@@MOUNTUSR@@/mount.usr=\/dev\/mapper\/usr verity.usr/' > \
"${GRUB_TEMP_DIR}/grub.cfg"
else
# uses standard systemd /usr mount
cat "${BUILD_LIBRARY_DIR}/grub.cfg" | \
sed 's/@@MOUNTUSR@@/mount.usr/' > "${GRUB_TEMP_DIR}/grub.cfg"
fi
sudo tar cf "${ESP_DIR}/coreos/grub/grub.cfg.tar" \ sudo tar cf "${ESP_DIR}/coreos/grub/grub.cfg.tar" \
-C "${BUILD_LIBRARY_DIR}" "grub.cfg" -C "${GRUB_TEMP_DIR}" "grub.cfg"
fi fi
info "Generating ${GRUB_DIR}/${CORE_NAME}" info "Generating ${GRUB_DIR}/${CORE_NAME}"

View File

@ -76,21 +76,8 @@ create_prod_image() {
L+ /etc/ld.so.conf - - - - ../usr/lib/ld.so.conf L+ /etc/ld.so.conf - - - - ../usr/lib/ld.so.conf
EOF EOF
# Only try to disable rw on /usr if there is a /usr partition
local disable_read_write=${FLAGS_enable_rootfs_verification}
if ! mountpoint -q "${root_fs_dir}/usr"; then
disable_read_write=${FLAGS_FALSE}
fi
finish_image "${image_name}" "${disk_layout}" "${root_fs_dir}" "${image_contents}" finish_image "${image_name}" "${disk_layout}" "${root_fs_dir}" "${image_contents}"
# Make the filesystem un-mountable as read-write and setup verity.
if [[ ${disable_read_write} -eq ${FLAGS_TRUE} ]]; then
"${BUILD_LIBRARY_DIR}/disk_util" --disk_layout="${disk_layout}" verity \
--root_hash="${BUILD_DIR}/${image_name%.bin}_verity.txt" \
"${BUILD_DIR}/${image_name}"
fi
upload_image -d "${BUILD_DIR}/${image_name}.bz2.DIGESTS" \ upload_image -d "${BUILD_DIR}/${image_name}.bz2.DIGESTS" \
"${BUILD_DIR}/${image_contents}" \ "${BUILD_DIR}/${image_contents}" \
"${BUILD_DIR}/${image_packages}" \ "${BUILD_DIR}/${image_packages}" \