Skip to content

Commit

Permalink
TEST-67-INTEGRITY: several fixes (systemd#35366)
Browse files Browse the repository at this point in the history
  • Loading branch information
bluca authored Nov 27, 2024
2 parents 03ad02c + 6bb3771 commit f7d4235
Showing 1 changed file with 88 additions and 85 deletions.
173 changes: 88 additions & 85 deletions test/units/TEST-67-INTEGRITY.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,120 +2,123 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
set -euxo pipefail

export DM_NAME="integrity_test"
export FULL_DM_DEV_NAME="/dev/mapper/${DM_NAME}"
export FS_UUID="01234567-ffff-eeee-eeee-0123456789ab"
export GEN="/var/run/systemd/generator"
DM_NAME="integrity_test"
DM_NODE="/dev/mapper/${DM_NAME}"
DM_SERVICE="systemd-integritysetup@${DM_NAME}.service"
FS_UUID="01234567-ffff-eeee-eeee-0123456789ab"

image_dir=""
TMP_DIR=
LOOP=

cleanup()
{
if [ -z "${image_dir}" ]; then
return
cleanup() (
set +e

if [[ -n "${LOOP}" ]]; then
losetup -d "${LOOP}"
fi

if [ -f "${image_dir}/image" ]; then
if [ -e "${FULL_DM_DEV_NAME}" ]; then
integritysetup close "${DM_NAME}"
fi
losetup -d "${loop}"
if [[ -n "${TMP_DIR}" ]]; then
rm -rf "${TMP_DIR}"
fi

rm -rf "${image_dir}"
}
rm -rf /run/udev/rules.d/
udevadm control --reload
)

trap cleanup EXIT

build_integrity_tab()
{
cat <<EOF >"/etc/integritytab"
${DM_NAME} ${loop} - integrity-algorithm=$1
udevadm settle

# Enable debugging logs for loop and dm block devices.
mkdir -p /run/udev/rules.d/
cat >/run/udev/rules.d/00-integrity-test.rules <<EOF
SUBSYSTEM=="block", KERNEL=="loop*|dm-*", OPTIONS="log_level=debug"
EOF
}

image_dir="$(mktemp -d -t -p / integrity.tmp.XXXXXX)"
if [ -z "${image_dir}" ] || [ ! -d "${image_dir}" ]; then
echo "mktemp under / failed"
exit 1
fi
# FIXME:
# There is no ordering restriction between underlying loopback block devices and DM devices.
# Hence, we may get wrong device node symlinks. To workaround that issue, let's decrease the
# priority for loopback block devices.
cat >/run/udev/rules.d/99-priority.rules <<EOF
SUBSYSTEM=="block", KERNEL=="loop*", OPTIONS="link_priority=-200"
EOF

dd if=/dev/zero of="${image_dir}/image" bs=1048576 count=64 || exit 1
dd if=/dev/zero of="${image_dir}/data" bs=1048576 count=64 || exit 1
loop="$(losetup --show -f "${image_dir}/image")"
udevadm control --reload

if [[ ! -e ${loop} ]]; then
echo "Loopback device created not found!"
exit 1
fi
TMP_DIR="$(mktemp -d -t -p / integrity.tmp.XXXXXX)"
dd if=/dev/zero of="${TMP_DIR}/image" bs=1048576 count=64
dd if=/dev/zero of="${TMP_DIR}/data" bs=1048576 count=64
LOOP="$(losetup --show -f "${TMP_DIR}/image")"
udevadm wait --timeout=30 --settle "${LOOP}"

# Do one iteration with a separate data device, to test those branches
separate_data=1
test_cleanup() (
set +e

for algorithm in crc32c crc32 xxhash64 sha1 sha256
do
if [ "${separate_data}" -eq 1 ]; then
data_option="--data-device=${image_dir}/data"
else
data_option=""
if [[ -e "/run/systemd/generator/${DM_SERVICE}" ]]; then
systemctl stop "${DM_SERVICE}"
elif [[ -e "${DM_NODE}" ]]; then
integritysetup close "${DM_NAME}"
fi
integritysetup format "${loop}" --batch-mode -I "${algorithm}" "${data_option}" || exit 1
integritysetup open -I "${algorithm}" "${loop}" "${DM_NAME}" "${data_option}" || exit 1
mkfs.ext4 -U "${FS_UUID}" "${FULL_DM_DEV_NAME}" || exit 1

# Give userspace time to handle udev events for new FS showing up ...
udevadm settle
udevadm wait --timeout=30 --settle --removed "${DM_NODE}"

# Clear integritytab.
rm -f /etc/integritytab

# Make the generator to re-run.
systemctl daemon-reload
)

integritysetup close "${DM_NAME}" || exit 1
test_one() {
local algorithm="${1?}"
local separate_data="${2?}"
local data_option

# create integritytab, generate units, start service
if [ "${separate_data}" -eq 1 ]; then
data_option=",data-device=${image_dir}/data"
trap test_cleanup RETURN

if [[ "${separate_data}" == 1 ]]; then
data_option="--data-device=${TMP_DIR}/data"
else
data_option=""
fi
build_integrity_tab "${algorithm}${data_option}"

# Cause the generator to re-run
systemctl daemon-reload || exit 1

# Check for existence of unit files...
if [[ ! -e "/run/systemd/generator/systemd-integritysetup@${DM_NAME}.service" ]]; then
echo "Service file does not exist!"
exit 1
fi
integritysetup format "${LOOP}" --batch-mode -I "${algorithm}" "${data_option}"
integritysetup open -I "${algorithm}" "${LOOP}" "${DM_NAME}" "${data_option}"
udevadm wait --timeout=30 --settle "${DM_NODE}"
mkfs.ext4 -U "${FS_UUID}" "${DM_NODE}"
# Wait for synthetic events being processed.
udevadm settle
integritysetup close "${DM_NAME}"
udevadm wait --timeout=30 --settle --removed "${DM_NODE}"

# Make sure we are in a consistent state, e.g. not already active before we start
systemctl stop systemd-integritysetup@"${DM_NAME}".service || exit 1
systemctl start systemd-integritysetup@"${DM_NAME}".service || exit 1
# Reset the start-limit counters, as we're going to restart the service a couple of times
systemctl reset-failed systemd-integritysetup@"${DM_NAME}".service

# Check the signature on the FS to ensure we can retrieve it and that is matches
if [ -e "${FULL_DM_DEV_NAME}" ]; then
# If a separate device is used for the metadata storage, then blkid will return one of the loop devices
if [ "${separate_data}" -eq 1 ]; then
dev_name="$(integritysetup status ${DM_NAME} | grep '^\s*device:' | awk '{print $2}')"
else
dev_name="${FULL_DM_DEV_NAME}"
fi
if [ "${dev_name}" != "$(blkid -U "${FS_UUID}")" ]; then
echo "Failed to locate FS with matching UUID!"
exit 1
fi
# Create integritytab.
if [[ "${separate_data}" == 1 ]]; then
data_option=",data-device=${TMP_DIR}/data"
else
echo "Failed to bring up integrity device!"
exit 1
data_option=""
fi
cat >"/etc/integritytab" <<EOF
${DM_NAME} ${LOOP} - integrity-algorithm=${algorithm}${data_option}
EOF

systemctl stop systemd-integritysetup@"${DM_NAME}".service || exit 1
# Make the generator to re-run.
systemctl daemon-reload

if [ -e "${FULL_DM_DEV_NAME}" ]; then
echo "Expecting ${FULL_DM_DEV_NAME} to not exist after stopping unit!"
exit 1
fi
# Check for existence of the unit file.
[[ -e "/run/systemd/generator/${DM_SERVICE}" ]]

# Make sure we are in a consistent state, e.g. not already active before we start.
[[ "$(systemctl is-active "${DM_SERVICE}")" == inactive ]]
systemctl start "${DM_SERVICE}"
udevadm wait --timeout=30 --settle "${DM_NODE}"

# Check the signature on the FS to ensure we can retrieve it and that is matches.
[[ "$(blkid -U "${FS_UUID}")" == "${DM_NODE}" ]]
}

separate_data=0
for a in crc32c crc32 xxhash64 sha1 sha256; do
test_one "$a" 0
test_one "$a" 1
done

touch /testok

0 comments on commit f7d4235

Please sign in to comment.