From d7c9e8250d56a471e44545923db76c0ae413e37a Mon Sep 17 00:00:00 2001 From: Jim Hebert Date: Thu, 27 Jan 2011 15:44:51 -0800 Subject: [PATCH] Add script to validate kernel params before we sign images Change-Id: I8ffedf8afa00862d135f80db9350927cc0332979 BUG=chrome-os-partner:1991 TEST=Have run it manually with various config data producing test-pass and the different sources of test-fails Review URL: http://codereview.chromium.org/6253014 --- .../ensure_secure_kernelparams.config | 40 ++++++ .../ensure_secure_kernelparams.sh | 115 ++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100755 scripts/image_signing/ensure_secure_kernelparams.config create mode 100755 scripts/image_signing/ensure_secure_kernelparams.sh diff --git a/scripts/image_signing/ensure_secure_kernelparams.config b/scripts/image_signing/ensure_secure_kernelparams.config new file mode 100755 index 0000000000..bf2582bacf --- /dev/null +++ b/scripts/image_signing/ensure_secure_kernelparams.config @@ -0,0 +1,40 @@ +#!/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. + +# +# COMMON +# +required_kparams_common=( quiet console=tty2 init=/sbin/init add_efi_memmap + boot=local rootwait ro noresume noswap i915.modeset=1 + loglevel=1 cros_secure kern_guid=%U tpm_tis.force=1 + tpm_tis.interrupts=0 root=/dev/dm-0 + dm_verity.error_behavior=3 dm_verity.max_bios=-1 + dm_verity.dev_wait=1 noinitrd ) + +optional_kparams_common=( ) + +# use "MAGIC_HASH" in place of the unpredictable sha1 hash, comparison +# functions later take care of the rest.... This set of dmparams +# taken from observation of current builds. In particular we may see +# the size of the filesystem creep over time. That size is denoted by +# the large number that appears a couple times in this string. +required_dmparams_common="vroot none ro,0 1740800 verity /dev/sd%D%P \ +/dev/sd%D%P 1740800 1 sha1 MAGIC_HASH" + + +# +# x86-mario +# +required_kparams_x86_mario=( ${required_kparams_common[@]} ) +optional_kparams_x86_mario=( ${optional_kparams_common[@]} ) +required_dmparams_x86_mario="$required_dmparams_common" + +# +# x86-agz +# +required_kparams_x86_agz=( ${required_kparams_common[@]} ) +optional_kparams_x86_agz=( ${optional_kparams_common[@]} ) +required_dmparams_x86_agz="$required_dmparams_common" diff --git a/scripts/image_signing/ensure_secure_kernelparams.sh b/scripts/image_signing/ensure_secure_kernelparams.sh new file mode 100755 index 0000000000..1d159d4c6c --- /dev/null +++ b/scripts/image_signing/ensure_secure_kernelparams.sh @@ -0,0 +1,115 @@ +#!/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 a long and unpredictable +# sha1 hash, return the same string with the sha1 hash replaced +# with a magic placeholder. This same magic placeholder is used +# in the config file, for comparison purposes. +dmparams_mangle_sha1() { + echo "$1" | sed 's/sha1 [0-9a-fA-F]*/sha1 MAGIC_HASH/' +} + +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 + + if [[ $# -ne 1 ]] && [[ $# -ne 2 ]]; then + usage + exit 1 + fi + + local image="$1" + + # 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" + + local kernelblob=$(make_temp_file) + extract_image_partition "$image" 2 "$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 "optional_kparams=(\${optional_kparams_$board[@]})" + eval "required_dmparams=\"\$required_dmparams_$board\"" + + # Divide the dm params from the rest and process seperately. + local kparams=$(dump_kernel_config "$kernelblob") + local dmparams=$(dmparams_mangle_sha1 "$(get_dmparams "$kparams")") + local kparams_nodm=$(kparams_remove_dm "$kparams") + + # Special-case handling of the dm= param: + if [[ "$dmparams" != "$required_dmparams" ]]; then + echo "Kernel dm= parameter does not match expected value!" + echo "Expected: $required_dmparams" + echo "Actual: $dmparams" + testfail=1 + 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. + kparams_nodm=${kparams_nodm/$param/} + fi + done + + # Check-off each of the allowed-but-optional params that were present. + for param in ${optional_kparams[@]}; do : + kparams_nodm=${kparams_nodm/$param/} + 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: $kparams_nodm" + testfail=1 + fi + + exit $testfail +} + +main $@