#!/bin/bash # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- # ex: ts=8 sw=4 sts=4 et filetype=sh # This script generates a service that manages a dm-verity device for the chosen ROOT partition set -e cmdline=( $(</proc/cmdline) ) # Usage: cmdline_arg name default_value cmdline_arg() { local name="$1" value="$2" for arg in "${cmdline[@]}"; do if [[ "${arg%%=*}" == "${name}" ]]; then value="${arg#*=}" fi done echo "${value}" } UNIT_DIR="${1:-/tmp}" root=$(cmdline_arg verity.root) roothash=$(cmdline_arg verity.roothash) hashoffset=$(cmdline_arg verity.hashoffset) case "${root}" in LABEL=*) root="$(echo $root | sed 's,/,\\x2f,g')" root="/dev/disk/by-label/${root#LABEL=}" ;; UUID=*) root="${root#UUID=}" root="/dev/disk/by-uuid/${root,,}" ;; PARTUUID=*) root="${root#PARTUUID=}" root="/dev/disk/by-partuuid/${root,,}" ;; PARTLABEL=*) root="/dev/disk/by-partlabel/${root#PARTLABEL=}" ;; esac # Only proceed if the source is a path. if [[ "${root}" != /* ]]; then exit 0 fi # Only generate the service if we have sufficient parameters. if [[ -n "${root}" && -n "${roothash}" ]]; then device=$(systemd-escape --suffix=device --path "${root}") cat >"${UNIT_DIR}/verity-setup.service" <<-EOF # Automatically generated by verity-generator [Unit] Description=Verity Setup for /dev/mapper/root SourcePath=/proc/cmdline DefaultDependencies=no IgnoreOnIsolate=true BindsTo=dev-mapper-root.device BindsTo=${device} After=${device} [Service] Type=oneshot RemainAfterExit=yes ExecStart=/bin/sh -c '/sbin/veritysetup create root ${hashoffset:+--hash-offset="${hashoffset}"} "${root}" "${root}" "${roothash}"' ExecStop=/sbin/veritysetup remove root EOF requires_dir="${UNIT_DIR}/dev-mapper-root.device.requires" mkdir -p "${requires_dir}" ln -sf "../verity-setup.service" "${requires_dir}/verity-setup.service" fi