Skip to content

Commit

Permalink
Add support for 'rootfs: verity' (and use for /boot if possible)
Browse files Browse the repository at this point in the history
I'd like to move in the direction of using fs-verity.  First, if
we detect the target kernel has `CONFIG_FS_VERITY`, we use it
unconditionally for `/boot` since that's already ext4, and we don't
need reflinks there.

To aid further development work here, add `rootfs: verity` as an option
in `image.yaml`.  But this isn't the default because we don't
want to trade off incomplete security for performance (reflinks).
  • Loading branch information
cgwalters committed Dec 6, 2019
1 parent e039a82 commit f8a25fe
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 8 deletions.
30 changes: 28 additions & 2 deletions src/cmd-buildextend-metal
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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"
mv "${path}.tmp" "$path"
echo "{}" > tmp/vm-iso-checksum.json
Expand Down
42 changes: 36 additions & 6 deletions src/create_disk.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,17 @@ 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'.
EOC
}

rootfs_size="0"
luks_rootfs=""
boot_verity=0
rootfs="xfs"
extrakargs=""

while [ $# -gt 0 ];
Expand All @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -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}"

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down

0 comments on commit f8a25fe

Please sign in to comment.