diff --git a/src/cmd-buildextend-metal b/src/cmd-buildextend-metal index fa425973b4..9609b15374 100755 --- a/src/cmd-buildextend-metal +++ b/src/cmd-buildextend-metal @@ -166,6 +166,27 @@ else rootfs_size="${rootfs_size}M" fi +disk_args=() + +set -x +# Extract the target kernel config, which may inform how we build disks. +target_moduledir=$(ostree --repo="${tmprepo}" ls "${commit}" /usr/lib/modules | grep -o '/usr/lib/modules/.*') +ostree --repo="${tmprepo}" cat "${commit}" "${target_moduledir}/config" > tmp/target-kernel.config +# Part of: https://github.com/ostreedev/ostree/pull/1959 +# We need to support kernels that don't have this enabled yet, including RHEL8 +# and current Fedora 31. +# https://bugzilla.redhat.com/show_bug.cgi?id=1765933 +# We unconditonally enable fs-verity for /boot if we have it, +# because...integrity there is useful a bit and it will help +# us prove this out even if we're not using it for the rootfs. +if grep -Eq '^CONFIG_FS_VERITY=y' tmp/target-kernel.config; then + disk_args+=("--boot-verity") +else + echo 'NOTE: Missing CONFIG_FS_VERITY from target kernel config' + sleep 1 +fi +rm tmp/target-kernel.config + kargs="$(python3 -c 'import sys, yaml; args = yaml.safe_load(sys.stdin).get("extra-kargs", []); print(" ".join(args))' < "$configdir/image.yaml")" tty="console=tty0 console=${DEFAULT_TERMINAL},115200n8" # On each s390x hypervisor, a tty would be automatically detected by the kernel @@ -178,7 +199,11 @@ kargs="$kargs $tty ignition.platform.id=$ignition_platform_id" ostree_remote="$(python3 -c 'import sys, yaml; print(yaml.safe_load(sys.stdin).get("ostree-remote", "NONE"))' < "$configdir/image.yaml")" save_var_subdirs="$(python3 -c 'import sys, yaml; print(yaml.safe_load(sys.stdin).get("save-var-subdirs-for-selabel-workaround", "NONE"))' < "$configdir/image.yaml")" -luks_flag="$(python3 -c 'import sys, yaml; lf=yaml.safe_load(sys.stdin).get("luks_rootfs", ""); print("--luks-rootfs" if lf.lower() in ("yes", "true") else "")' < "$configdir/image.yaml")" +# First parse the old luks_rootfs flag +rootfs_type="$(python3 -c 'import sys, yaml; lf=yaml.safe_load(sys.stdin).get("luks_rootfs", ""); print("luks" if lf.lower() in ("yes", "true") else "")' < "$configdir/image.yaml")" +if [ -z "${rootfs_type}" ]; then + rootfs_type="$(python3 -c 'import sys, yaml; print(yaml.safe_load(sys.stdin).get("rootfs", "xfs"))' < "$configdir/image.yaml")" +fi qemu-img create -f ${image_format} "${path}.tmp" "${image_size}" # We support deploying a commit directly instead of a ref @@ -205,7 +230,8 @@ runvm "${target_drive[@]}" -- \ --ostree-repo "${ostree_repo}" \ --save-var-subdirs "${save_var_subdirs}" \ --rootfs-size "${rootfs_size}" \ - "${luks_flag}" + --rootfs "${rootfs_type}" \ + "${disk_args[@]}" /usr/lib/coreos-assembler/finalize-artifact "${path}.tmp" "${path}" echo "{}" > tmp/vm-iso-checksum.json diff --git a/src/create_disk.sh b/src/create_disk.sh index b83ef094a1..9a0da68799 100755 --- a/src/create_disk.sh +++ b/src/create_disk.sh @@ -28,7 +28,8 @@ Options: --ostree-repo: location of the ostree repo --save-var-subdirs: "yes" to workaround selabel issue for RHCOS --rootfs-size: Create the root filesystem with specified size - --luks-rootfs: place rootfs in a LUKS container + --boot-verity: Provide this to enable ext4 fs-verity for /boot + --rootfs: xfs|ext4verity|luks You probably don't want to run this script by hand. This script is run as part of 'coreos-assembler build'. @@ -36,7 +37,8 @@ EOC } rootfs_size="0" -luks_rootfs="" +boot_verity=0 +rootfs="xfs" extrakargs="" while [ $# -gt 0 ]; @@ -55,7 +57,8 @@ do --ostree-repo) ostree="${1}"; shift;; --save-var-subdirs) save_var_subdirs="${1}"; shift;; --rootfs-size) rootfs_size="${1}"; shift;; - --luks-rootfs) luks_rootfs=1;; + --boot-verity) boot_verity=1;; + --rootfs) rootfs="${1}" shift;; *) echo "${flag} is not understood."; usage; exit 10;; --) break; esac; @@ -78,6 +81,11 @@ grub_script="${grub_script:?--grub-script must be defined}" os_name="${os_name:?--os_name must be defined}" save_var_subdirs="${save_var_subdirs:?--save_var_subdirs must be defined}" +case "${rootfs}" in + xfs|ext4verity|luks) ;; + *) echo "Invalid rootfs type: ${rootfs}" 1>&2; exit 1;; +esac + set -x # Partition and create fs's. The 0...4...a...1 uuid is a sentinal used by coreos-gpt-setup @@ -133,7 +141,7 @@ esac udevtrig root_dev="${disk}${ROOTPN}" -if [ -n "${luks_rootfs}" ]; then +if [ "${rootfs}" = "luks" ]; then root_dev=/dev/mapper/crypt_root sgdisk -c ${ROOTPN}:luks_root "${disk}" @@ -176,13 +184,32 @@ if [ -n "${luks_rootfs}" ]; then extrakargs="${extrakargs} rd.luks.options=discard" fi -mkfs.ext4 "${disk}${BOOTPN}" -L boot +bootargs= +if [ "${boot_verity}" = 1 ]; then + # Need 4k blocks to match host page size; TODO + # really mkfs.ext4 should know this. This is arch-dependent probably. + bootargs="-b 4096 -O verity" +fi +mkfs.ext4 ${bootargs} "${disk}${BOOTPN}" -L boot if [ ${EFIPN:+x} ]; then mkfs.fat "${disk}${EFIPN}" -n EFI-SYSTEM # partition $BIOPN has no FS, its for bios grub # partition $PREPPN has no FS, its for PowerPC PReP Boot fi -mkfs.xfs "${root_dev}" -L root -m reflink=1 +if [ "${rootfs}" = "ext4verity" ]; then + # As of today, xfs doesn't support verity, so we have a choice of fs-verity or reflinks. + # Now, fs-verity doesn't in practice gain us a huge amount of security because + # there are other "persistence vectors". See + # https://blog.verbum.org/2017/06/12/on-dm-verity-and-operating-systems/ + # https://github.com/coreos/rpm-ostree/issues/702 + # And reflinks are *very* useful for the container stack with overlayfs (and in general). + # So basically, we're choosing performance over half-implemented security. + # Eventually, we'd like both - once XFS gains verity (probably not too hard), + # we could unconditionally enable it there. + mkfs.ext4 -O verity -L root "${root_dev}" +else + mkfs.xfs "${root_dev}" -L root -m reflink=1 +fi rootfs=$PWD/tmp/rootfs @@ -211,6 +238,9 @@ mkdir -p $rootfs/ostree chcon $(matchpathcon -n /ostree) $rootfs/ostree mkdir -p $rootfs/ostree/{repo,deploy} ostree --repo=$rootfs/ostree/repo init --mode=bare +if [ "${rootfs}" = "ext4verity" ]; then + ostree config --repo=$rootfs/ostree/repo set fsverity.required 'true' +fi remote_arg= deploy_ref="${ref}" if [ "${remote_name}" != NONE ]; then