build_image, build_kernel_image, update_bootloaders: fix up rootfs_verification

This change adds
- --rootfs_hash_pad to specify the MBs reserved for the pad
- the implementation of the above flag
- check if total fs size + pad size exceeds the partition size
- hash appending in make_image_bootable()

Fixes:
- a style for ROOT_FS_HASH usage
- bad mount|grep
- bad bash subst for root devices in all boot paths
- fixed a typo in the update_bootloaders table creation
- disables verified usb for now

Adding the padding argument ensures that the generated hash tree for the root filesystem is appended to the image.  Assuming the rootfs is _never_ mounted read-write
again, that hash tree will be valid and vboot will be able to proceed.

BUG=chromium-os:2693
TEST=manual build_image

Review URL: http://codereview.chromium.org/3043011

Change-Id: I67d9b0f91cacdefa309c0cc2dd7fed1d2eddd7a7
This commit is contained in:
Will Drewry 2010-07-21 14:02:20 -05:00
parent e79e88eb0e
commit 78992a33f4
4 changed files with 52 additions and 19 deletions

View File

@ -51,6 +51,9 @@ DEFINE_integer rootfs_partition_size 1024 \
"rootfs parition size in MBs."
DEFINE_integer rootfs_size 720 \
"rootfs filesystem size in MBs."
# ceil(0.1 * rootfs_size) is a good minimum.
DEFINE_integer rootfs_hash_pad 8 \
"MBs reserved at the end of the rootfs image."
DEFINE_integer statefulfs_size 1024 \
"stateful filesystem size in MBs."
DEFINE_boolean preserve ${FLAGS_FALSE} \
@ -91,8 +94,10 @@ if [ -z "${FLAGS_board}" ] ; then
exit 1
fi
if [ "${FLAGS_rootfs_size}" -gt "${FLAGS_rootfs_partition_size}" ] ; then
error "rootfs (${FLAGS_rootfs_size} MB) is bigger than partition (${FLAGS_rootfs_partition_size} MB)."
if [ "$((FLAGS_rootfs_size + FLAGS_rootfs_hash_pad))" -gt \
"${FLAGS_rootfs_partition_size}" ] ; then
error "rootfs ($((FLAGS_rootfs_size + FLAGS_rootfs_hash_pad)) MB) is \
bigger than partition (${FLAGS_rootfs_partition_size} MB)."
exit 1
fi
@ -293,8 +298,10 @@ make_image_bootable() {
--image "${image_name}" -r "${ROOT_FS_DIR}" \
-s "${STATEFUL_FS_DIR}"
# The rootfs should never be mounted rw again after this point without
# re-calling make_image_bootable.
sudo mount -o remount,ro "${ROOT_FS_DIR}"
root_dev=$(mount | grep -- "${ROOT_FS_DIR}" | cut -f1 -d' ' | tail -1)
root_dev=$(mount | grep -- "on ${ROOT_FS_DIR} type" | cut -f1 -d' ' | tail -1)
DEVKEYSDIR="/usr/share/vboot/devkeys"
@ -308,7 +315,7 @@ make_image_bootable() {
--working_dir="${OUTPUT_DIR}" \
--keep_work \
--rootfs_image=${root_dev} \
--rootfs_hash=${OUTPUT_DIR}/rootfs.hash \
--rootfs_hash=${ROOT_FS_HASH} \
--verity_hash_alg=${FLAGS_verity_algorithm} \
--verity_tree_depth=${FLAGS_verity_depth} \
--verity_max_ios=${FLAGS_verity_max_ios} \
@ -316,6 +323,25 @@ make_image_bootable() {
--root=${cros_root} \
--keys_dir="${DEVKEYSDIR}"
local rootfs_hash_size=$(stat -c '%s' ${ROOT_FS_HASH})
info "Appending rootfs.hash (${rootfs_hash_size} bytes) to the root fs"
if [[ ${rootfs_hash_size} -gt $((FLAGS_rootfs_hash_pad * 1024 * 1024)) ]]
then
die "--rootfs_hash_pad reserves less than the needed ${rootfs_hash_size}"
fi
# Unfortunately, mount_gpt_image uses mount and not losetup to create the
# loop devices. This means that they are not the correct size. We have to
# write directly to the image to append the hash tree data.
local hash_offset="$(partoffset ${OUTPUT_DIR}/${image_name} 3)"
hash_offset=$((hash_offset + ((1024 * 1024 * ${FLAGS_rootfs_size}) / 512)))
sudo dd bs=512 \
seek=${hash_offset} \
if="${ROOT_FS_HASH}" \
of="${OUTPUT_DIR}/${image_name}" \
conv=notrunc
# We don't need to keep the file around anymore.
sudo rm "${ROOT_FS_HASH}"
# Move the verification block needed for the hard disk install to the
# stateful partition. Mount stateful fs, copy file, and umount fs.
# In original CL: http://codereview.chromium.org/2868044, this was done in
@ -510,7 +536,18 @@ create_base_image() {
sudo losetup "${LOOP_DEV}" "${ROOT_FS_IMG}"
sudo mkfs.ext3 "${LOOP_DEV}"
# Pad out 10% for the hash tree. This currently _exact_ for
# default configuration. More space may be needed for different options.
ROOT_HASH_PAD=$((FLAGS_rootfs_hash_pad * 1024 * 1024))
info "Padding the rootfs image by ${ROOT_HASH_PAD} bytes for hash data"
dd if=/dev/zero of="${ROOT_FS_IMG}" bs=1 count=1 \
seek=$((ROOT_SIZE_BYTES + ROOT_HASH_PAD - 1))
# Update to reflect the new capacity in the loop device.
sudo losetup -c "${LOOP_DEV}"
# Tune and mount rootfs.
# TODO(wad) rename the disk label to match the GPT since we
# can't change it later.
DISK_LABEL="C-KEYFOB"
sudo tune2fs -L "${DISK_LABEL}" -U "${UUID}" -c 0 -i 0 "${LOOP_DEV}"
sudo mount "${LOOP_DEV}" "${ROOT_FS_DIR}"

View File

@ -58,17 +58,16 @@ set -e
verity_args=
# Even with a rootfs_image, root= is not changed unless specified.
if [[ -n "${FLAGS_rootfs_image}" && -n "${FLAGS_rootfs_hash}" ]]; then
info "Determining root fs block count."
# Gets the number of blocks. 4096 byte blocks _are_ expected.
root_fs_blocks=$(sudo dumpe2fs "${FLAGS_rootfs_image}" 2> /dev/null |
grep "Block count" |
tr -d ' ' |
cut -f2 -d:)
info "Checking root fs block size."
root_fs_block_sz=$(sudo dumpe2fs "${FLAGS_rootfs_image}" 2> /dev/null |
grep "Block size" |
tr -d ' ' |
cut -f2 -d:)
info "rootfs is ${root_fs_blocks} blocks of ${root_fs_block_sz} bytes"
if [[ ${root_fs_block_sz} -ne 4096 ]]; then
error "Root file system blocks are not 4k!"
fi
@ -87,10 +86,10 @@ if [[ -n "${FLAGS_rootfs_image}" && -n "${FLAGS_rootfs_hash}" ]]; then
# the verified boot device. Doing so will claim /dev/sdDP out from
# under the system.
if [[ ${FLAGS_root} = "/dev/dm-0" ]]; then
table=${table//HASH_DEV/\/dev\/sd%D%P}
table=${table//ROOT_DEV/\/dev\/sd%D%P}
table=${table//HASH_DEV//dev/sd%D%P}
table=${table//ROOT_DEV//dev/sd%D%P}
fi
verity_args="dm=\"${table}\""
verity_args="dm=\"vroot none ro,${table}\""
info "dm-verity configuration: ${verity_args}"
fi

View File

@ -99,15 +99,13 @@ EOF
info "Emitted ${SYSLINUX_DIR}/syslinux.cfg"
if [[ ${FLAGS_enable_rootfs_verification} -eq ${FLAGS_TRUE} ]]; then
# TODO(wad, tgao) enable usb vbooting with initramfs or device probing.
warn "USB booting will not use rootfs verification."
fi
# To change the active target, only this file needs to change.
cat <<EOF | sudo dd of="${SYSLINUX_DIR}/default.cfg" 2>/dev/null
DEFAULT chromeos-vusb.A
EOF
else
cat <<EOF | sudo dd of="${SYSLINUX_DIR}/default.cfg" 2>/dev/null
DEFAULT chromeos-usb.A
EOF
fi
info "Emitted ${SYSLINUX_DIR}/default.cfg"
cat <<EOF | sudo dd of="${SYSLINUX_DIR}/usb.A.cfg" 2>/dev/null

View File

@ -72,8 +72,7 @@ if ! type -p update_x86_bootloaders; then
sudo dd of="${esp_fs_dir}"/efi/boot/grub.cfg
# Rewrite syslinux DM_TABLE
usb_target="${FLAGS_usb_disk//\//\\\/}"
syslinux_dm_table_usb=${dm_table//\/dev\/${old_root}/${usb_target}}
syslinux_dm_table_usb=${dm_table//\/dev\/${old_root}/${FLAGS_usb_disk}}
sed -e "s|DMTABLEA|${syslinux_dm_table_usb}|g" \
"${template_dir}"/syslinux/usb.A.cfg |
sudo dd of="${esp_fs_dir}"/syslinux/usb.A.cfg
@ -84,7 +83,7 @@ if ! type -p update_x86_bootloaders; then
sudo dd of="${esp_fs_dir}"/syslinux/root.A.cfg
syslinux_dm_table_b=${dm_table//\/dev\/${old_root}/HDROOTB}
sed -e "s|DMTABLEA|${syslinux_dm_table_a}|g" \
sed -e "s|DMTABLEB|${syslinux_dm_table_b}|g" \
"${template_dir}"/syslinux/root.B.cfg |
sudo dd of="${esp_fs_dir}"/syslinux/root.B.cfg