blob: 0098d9e5e16006e82af41535ef31e1841f18e0de [file] [edit]
#!/bin/sh
#
# 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.
#
# Helper function to dump VPD RO/RW content into /var/vpd_2.0.txt.
#
# Used in:
# + OOBE reads this log file for the default locale setting.
# + chrome://system reads filtered file.
#
umask 0077 # Conservative strategy. Allow root-only first. Open later.
# A temporary file used for caching the results of flashrom across subsequent
# invocations of the vpd utility within this script.
BIOS_TMP=$(mktemp)
# Files for temporary and final caching of full VPD data. Note that the
# temporary file is under /var/tmp to ensure that renaming (mv) is atomic.
CACHE_TMP=$(mktemp --tmpdir=/var/tmp)
CACHE_FILE="/var/cache/vpd/full-v2.cache"
# Location for storing cached ECHO coupon codes.
ECHO_COUPON_FILE="/var/cache/offers/vpd_echo.txt"
# A space delimited list of old VPD cache files, which will be removed as a
# cleanup measure. Please be sure to update this list as the cache filename
# changes between versions of this script!
OLD_CACHE_FILES="/var/cache/vpd/full.cache"
# Files for temporary and final storage of filtered VPD data. Note that the
# temporary file is under /var/tmp to ensure that renaming (mv) is atomic.
FILTERED_TMP=$(mktemp --tmpdir=/var/tmp)
FILTERED_FILE="/var/log/vpd_2.0.txt"
# Remove the temp file, which has full data if the script terminates early.
trap "rm -f ${BIOS_TMP} ${FILTERED_TMP} ${CACHE_TMP}" EXIT
# Load shflags, define script flags.
. /usr/share/misc/shflags
DEFINE_boolean "clean" ${FLAGS_FALSE} \
"Clean VPD cache and output files, then quit."
DEFINE_boolean "force" ${FLAGS_FALSE} \
"Force regeneration of VPD cache and output files."
DEFINE_boolean "full" ${FLAGS_FALSE} \
"Generate full output, without filtering."
DEFINE_boolean "stdout" ${FLAGS_FALSE} \
"Dump VPD to standard output, instead of a file."
# Change file ownership and permissions so it is world readable.
#
# $1: name of file to change ownership/permissions to.
set_world_readable() {
chown root:root "$1" || exit 1
chmod go-stwx "$1" || exit 1
chmod ugo+r "$1" || exit 1
}
# Generate a sed filter for VPD output depending on the provided flag.
#
# $1: Boolean flag: permit all output (true) or apply whitelist (false).
# $2, $3, ..: (Optional) Each parameter is one whitelisted key.
generate_sed_filter() {
local output=''
local all_output=$1
shift
if [ $all_output -eq ${FLAGS_FALSE} ]; then
for field in $*; do
output=${output}'/^"'${field}'"=/p;'
done
output=${output}'/^.*/d;'
fi
echo ${output}
}
# Generate the coupon code file containing cached VPD ECHO attributes.
generate_echo_codes() {
local echo_code_keys="
ubind_attribute
gbind_attribute"
mkdir -p $(dirname ${ECHO_COUPON_FILE})
sed -e "$(generate_sed_filter ${FLAGS_FALSE} ${echo_code_keys})" \
< ${CACHE_FILE} > ${ECHO_COUPON_FILE}
# Since chrome needs access to this, the file is readable by user chronos.
# Note: It should NOT be world readable.
# TODO(gauravsh): Broker this via debugd. http://crosbug.com/28285
chown -R chronos:chronos $(dirname ${ECHO_COUPON_FILE})
}
# Invoke the VPD utility for generating full VPD content.
#
# $1: BIOS filename
# $2: partition name
# $3: file name to append output
generate_full_text() {
(vpd -f "$1" -i "$2" -l || echo "# $2 execute error.") >> $3
}
#
# main()
#
# Parse arguments.
FLAGS "$@" || exit 1
eval set -- "${FLAGS_ARGV}"
# Cleanup: remove old versions of the VPD cache file; this ensures that we
# don't have unused VPD data lying around, which takes unnecessary space, might
# lead to stale VPD log extraction (in case of a script version rollback), and
# is perceived as a potential security breach.
rm -f ${OLD_CACHE_FILES}
# Remove output files if --clean or --force flagged.
if [ ${FLAGS_clean} -eq ${FLAGS_TRUE} -o \
${FLAGS_force} -eq ${FLAGS_TRUE} ]; then
rm -f ${FILTERED_FILE} ${CACHE_FILE}
# If --clean was flagged, we're done.
if [ ${FLAGS_clean} -eq ${FLAGS_TRUE} ]; then
exit 0
fi
fi
if [ ${FLAGS_stdout} -eq ${FLAGS_TRUE} ]; then
FILTERED_TMP=/dev/stdout
elif [ ${FLAGS_full} -eq ${FLAGS_TRUE} ]; then
# --full must only be used with --stdout, to prevent accidental dumping of
# sensitive VPD info into a world-readable file. To be used as follows:
#
# dump_vpd_log --full --stdout > a_root_readable_file
#
echo "You specified --full without --stdout, aborting."
exit 1
fi
# If the cache file is missing, generate it.
if [ ! -f ${CACHE_FILE} ]; then
flashrom -p internal:bus=spi -i FMAP -i RO_VPD -i RW_VPD -r ${BIOS_TMP} ||
flashrom -p internal:bus=spi -r ${BIOS_TMP}
mkdir -p $(dirname ${CACHE_FILE})
generate_full_text "${BIOS_TMP}" "RO_VPD" ${CACHE_TMP}
generate_full_text "${BIOS_TMP}" "RW_VPD" ${CACHE_TMP}
mv -f ${CACHE_TMP} ${CACHE_FILE}
# Remove existing filtered output file, forcing it to be regenerated.
rm -f ${FILTERED_FILE}
fi
# If the ECHO coupon cache is missing, generate it.
if [ ! -f ${ECHO_COUPON_FILE} ]; then
generate_echo_codes
fi
# Filter the full VPD output.
if [ ${FLAGS_stdout} -eq ${FLAGS_TRUE} -o \
! -f ${FILTERED_FILE} ]; then
WHITELIST="
initial_locale
keyboard_layout
initial_timezone
ActivateDate"
sed -e "$(generate_sed_filter ${FLAGS_full} ${WHITELIST})" < ${CACHE_FILE} \
> ${FILTERED_TMP}
# Rename temporary into permanent output if --stdout was not used.
if [ ${FLAGS_stdout} -eq ${FLAGS_FALSE} ]; then
set_world_readable ${FILTERED_TMP}
mv -f ${FILTERED_TMP} ${FILTERED_FILE}
fi
fi