mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-09 17:11:42 +00:00
The Linux kernel expects partitions that are identified by uuid, to have the the uuid prefixed by "PARTUUID=" and an optional suffix of "PARTRNOFF=%d". The change adds additional pattern matching for these strings. This will also let get rid of custom uuid processing in dm-verity, dm-bootcache and dm-verity-chromeos. BUG=chromium:224066 TEST=security_test_image with old and new command line BRANCH=none Change-Id: I71b89dd1df8d7ccd5768c2784078bb869d546bf3 Reviewed-on: https://gerrit.chromium.org/gerrit/51303 Reviewed-by: Mike Frysinger <vapier@chromium.org> Commit-Queue: Paul Taysom <taysom@chromium.org> Tested-by: Paul Taysom <taysom@chromium.org>
215 lines
7.9 KiB
Bash
Executable File
215 lines
7.9 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
# Abort on error.
|
|
set -e
|
|
|
|
# Load common constants and variables.
|
|
. "$(dirname "$0")/common.sh"
|
|
|
|
# Given a kernel boot param string which includes ...dm="dmstuff"...
|
|
# this returns the dmstuff by itself.
|
|
get_dmparams() {
|
|
echo "$1" | sed 's/^.*\ dm="\([^"]*\)".*/\1/'
|
|
}
|
|
|
|
# Given a kernel boot param string which includes ...dm="stuff"...
|
|
# this returns the param string with the dm="..." section removed.
|
|
# Useful in conjunction with get_dmparams to divide and process
|
|
# the two sections of parameters in seperate passes
|
|
kparams_remove_dm() {
|
|
echo "$1" | sed 's/dm="[^"]*"//'
|
|
}
|
|
|
|
# Given a dm param string which includes dynamic values, return the
|
|
# same string with these values replaced by a magic string placeholder.
|
|
# This same magic placeholder is used in the config file, for comparison
|
|
# purposes.
|
|
dmparams_mangle() {
|
|
local dmparams=$1
|
|
# First handle new key-value style verity parameters.
|
|
dmparams=$(echo "$dmparams" |
|
|
sed -e 's/root_hexdigest=[0-9a-fA-F]*/root_hexdigest=MAGIC_HASH/' |
|
|
sed -e 's/salt=[0-9a-fA-F]*/salt=MAGIC_SALT'/)
|
|
# If we didn't substitute the MAGIC_HASH yet, these are the old
|
|
# verity parameter format.
|
|
if [[ $dmparams != *MAGIC_HASH* ]]; then
|
|
dmparams=$(echo $dmparams | sed 's/sha1 [0-9a-fA-F]*/sha1 MAGIC_HASH/')
|
|
fi
|
|
# If we have bootcache enabled, replace its copy of the root_hexdigest
|
|
# with MAGIC_HASH. The parameter is positional.
|
|
if [[ $dmparams == *bootcache* ]]; then
|
|
dmparams=$(echo $dmparams |
|
|
sed -r 's:(bootcache (PARTUUID=)?%U(/PARTNROFF=|\+)1 [0-9]+) [0-9a-fA-F]+:\1 MAGIC_HASH:')
|
|
fi
|
|
echo $dmparams
|
|
}
|
|
|
|
# This escapes any non-alphanum character, since many such characters
|
|
# are regex metacharacters.
|
|
escape_regexmetas() {
|
|
echo "$1" | sed 's/\([^a-zA-Z0-9]\)/\\\1/g'
|
|
}
|
|
|
|
usage() {
|
|
echo "Usage $PROG image [config]"
|
|
}
|
|
|
|
main() {
|
|
# We want to catch all the discrepancies, not just the first one.
|
|
# So, any time we find one, we set testfail=1 and continue.
|
|
# When finished we will use testfail to determine our exit value.
|
|
local testfail=0
|
|
# A buffer to include useful information that we dump when things fail.
|
|
local output
|
|
|
|
if [[ $# -ne 1 ]] && [[ $# -ne 2 ]]; then
|
|
usage
|
|
exit 1
|
|
fi
|
|
|
|
local image="$1"
|
|
|
|
# A byte that should not appear in the command line to use as a sed
|
|
# marker when doing regular expression replacements.
|
|
local M=$'\001'
|
|
|
|
# Default config location: same name/directory as this script,
|
|
# with a .config file extension, ie ensure_secure_kernelparams.config.
|
|
local configfile="$(dirname "$0")/${0/%.sh/.config}"
|
|
# Or, maybe a config was provided on the command line.
|
|
if [[ $# -eq 2 ]]; then
|
|
configfile="$2"
|
|
fi
|
|
# Either way, load test-expectations data from config.
|
|
. "$configfile" || return 1
|
|
|
|
local kernelblob=$(make_temp_file)
|
|
# TODO(jimhebert): Perform the kernel security tests on both the kernel
|
|
# partitions. Here, we just run it on kernel partition 4
|
|
# which is the install kernel on the recovery image.
|
|
# crosbug.com/24274
|
|
extract_image_partition "$image" 4 "$kernelblob"
|
|
local rootfs=$(make_temp_dir)
|
|
mount_image_partition_ro "$image" 3 "$rootfs"
|
|
|
|
# Pick the right set of test-expectation data to use. The cuts
|
|
# turn e.g. x86-foo as a well as x86-foo-pvtkeys into x86_foo.
|
|
local board=$(grep CHROMEOS_RELEASE_BOARD= "$rootfs/etc/lsb-release" | \
|
|
cut -d = -f 2 | cut -d - -f 1,2 --output-delimiter=_)
|
|
eval "required_kparams=(\"\${required_kparams_$board[@]}\")"
|
|
eval "required_kparams_regex=(\"\${required_kparams_regex_$board[@]}\")"
|
|
eval "optional_kparams=(\"\${optional_kparams_$board[@]}\")"
|
|
eval "optional_kparams_regex=(\"\${optional_kparams_regex_$board[@]}\")"
|
|
eval "required_dmparams=(\"\${required_dmparams_$board[@]}\")"
|
|
eval "required_dmparams_regex=(\"\${required_dmparams_regex_$board[@]}\")"
|
|
output+="required_kparams=(\n"
|
|
output+="$(printf "\t'%s'\n" "${required_kparams[@]}")\n)\n"
|
|
output+="required_kparams_regex=(\n"
|
|
output+="$(printf "\t'%s'\n" "${required_kparams_regex[@]}")\n)\n"
|
|
output+="optional_kparams=(\n"
|
|
output+="$(printf "\t'%s'\n" "${optional_kparams[@]}")\n)\n"
|
|
output+="optional_kparams_regex=(\n"
|
|
output+="$(printf "\t'%s'\n" "${optional_kparams_regex[@]}")\n)\n"
|
|
output+="required_dmparams=(\n"
|
|
output+="$(printf "\t'%s'\n" "${required_dmparams[@]}")\n)\n"
|
|
output+="required_dmparams_regex=(\n"
|
|
output+="$(printf "\t'%s'\n" "${required_dmparams_regex[@]}")\n)\n"
|
|
|
|
# Divide the dm params from the rest and process seperately.
|
|
local kparams=$(dump_kernel_config "$kernelblob")
|
|
local dmparams=$(get_dmparams "$kparams")
|
|
local kparams_nodm=$(kparams_remove_dm "$kparams")
|
|
|
|
output+="\nkparams='${kparams}'\n"
|
|
output+="\ndmparams='${dmparams}'\n"
|
|
output+="\nkparams_nodm='${kparams_nodm}'\n"
|
|
|
|
mangled_dmparams=$(dmparams_mangle "${dmparams}")
|
|
output+="\nmangled_dmparams='${mangled_dmparams}'\n"
|
|
# Special-case handling of the dm= param:
|
|
testfail=1
|
|
for expected_dmparams in "${required_dmparams[@]}"; do
|
|
# Filter out all dynamic parameters.
|
|
if [ "$mangled_dmparams" = "$expected_dmparams" ]; then
|
|
testfail=0
|
|
break
|
|
fi
|
|
done
|
|
|
|
for expected_dmparams in "${required_dmparams_regex[@]}"; do
|
|
if [[ -z $(echo "${mangled_dmparams}" | \
|
|
sed "s${M}^${expected_dmparams}\$${M}${M}") ]]; then
|
|
testfail=0
|
|
break
|
|
fi
|
|
done
|
|
|
|
if [ $testfail -eq 1 ]; then
|
|
echo "Kernel dm= parameter does not match any expected values!"
|
|
echo "Actual: $dmparams"
|
|
echo "Expected: ${required_dmparams[@]}"
|
|
fi
|
|
|
|
# Ensure all other required params are present.
|
|
for param in "${required_kparams[@]}"; do
|
|
if [[ "$kparams_nodm" != *$param* ]]; then
|
|
echo "Kernel parameters missing required value: $param"
|
|
testfail=1
|
|
else
|
|
# Remove matched params as we go. If all goes well, kparams_nodm
|
|
# will be nothing left but whitespace by the end.
|
|
param=$(escape_regexmetas "$param")
|
|
kparams_nodm=$(echo " ${kparams_nodm} " |
|
|
sed "s${M} ${param} ${M} ${M}")
|
|
fi
|
|
done
|
|
|
|
# Ensure all other required regex params are present.
|
|
for param in "${required_kparams_regex[@]}"; do
|
|
if [[ "$kparams_nodm" != *$param* ]]; then
|
|
echo "Kernel parameters missing required value: $param"
|
|
testfail=1
|
|
else
|
|
# Remove matched params as we go. If all goes well, kparams_nodm
|
|
# will be nothing left but whitespace by the end.
|
|
kparams_nodm=$(echo " ${kparams_nodm} " |
|
|
sed "s${M} ${param} ${M} ${M}")
|
|
fi
|
|
done
|
|
|
|
# Check-off each of the allowed-but-optional params that were present.
|
|
for param in "${optional_kparams[@]}"; do
|
|
param=$(escape_regexmetas "$param")
|
|
kparams_nodm=$(echo " ${kparams_nodm} " |
|
|
sed "s${M} ${param} ${M} ${M}")
|
|
done
|
|
|
|
# Check-off each of the allowed-but-optional params that were present.
|
|
for param in "${optional_kparams_regex[@]}"; do
|
|
kparams_nodm=$(echo " ${kparams_nodm} " |
|
|
sed "s${M} ${param} ${M} ${M}")
|
|
done
|
|
|
|
# This section enforces the default-deny for any unexpected params
|
|
# not already processed by one of the above loops.
|
|
if [[ ! -z ${kparams_nodm// /} ]]; then
|
|
echo "Unexpected kernel parameters found:"
|
|
echo " $(echo "${kparams_nodm}" | sed -r 's: +: :g')"
|
|
testfail=1
|
|
fi
|
|
|
|
if [[ ${testfail} -eq 1 ]]; then
|
|
echo "Debug output:"
|
|
printf '%b\n' "${output}"
|
|
echo "(actual error will be at the top of output)"
|
|
fi
|
|
|
|
exit $testfail
|
|
}
|
|
|
|
main $@
|