| OLD | NEW |
| 1 #!/bin/sh -u | 1 #!/bin/sh -u |
| 2 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 2 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 # | 5 # |
| 6 # Run TPM diagnostics in recovery mode, and attempt to fix problems. This is | 6 # Run TPM diagnostics in recovery mode, and attempt to fix problems. This is |
| 7 # specific to devices with chromeos firmware. | 7 # specific to devices with chromeos firmware. |
| 8 # | 8 # |
| 9 # Usage: chromeos_tpm_recovery <log file> | 9 # Usage: chromeos_tpm_recovery <log file> |
| 10 # | 10 # |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 | 65 |
| 66 tpm_clear_and_reenable () { | 66 tpm_clear_and_reenable () { |
| 67 ensure_tcsd_is_not_running | 67 ensure_tcsd_is_not_running |
| 68 $tpmc clear | 68 $tpmc clear |
| 69 $tpmc enable | 69 $tpmc enable |
| 70 $tpmc activate | 70 $tpmc activate |
| 71 tpm_owned_with_well_known_password=0 | 71 tpm_owned_with_well_known_password=0 |
| 72 tpm_unowned=1 | 72 tpm_unowned=1 |
| 73 } | 73 } |
| 74 | 74 |
| 75 # We want the TPM owned with the well-known password. |
| 76 |
| 75 ensure_tpm_is_owned () { | 77 ensure_tpm_is_owned () { |
| 76 if [ $tpm_owned_with_well_known_password = 0 -a \ | 78 if [ $tpm_owned_with_well_known_password = 0 ]; then |
| 77 $tpm_unowned = 0 ]; then | |
| 78 tpm_clear_and_reenable | 79 tpm_clear_and_reenable |
| 79 ensure_tcsd_is_running | 80 ensure_tcsd_is_running |
| 80 $tpm_takeownership -y -z || log "takeownership failed with status $?" | 81 $tpm_takeownership -y -z || log "takeownership failed with status $?" |
| 81 tpm_owned_with_well_known_password=1 | 82 tpm_owned_with_well_known_password=1 |
| 82 tpm_unowned=0 | 83 tpm_unowned=0 |
| 83 fi | 84 fi |
| 84 } | 85 } |
| 85 | 86 |
| 86 ensure_tpm_is_unowned () { | 87 ensure_tpm_is_unowned () { |
| 87 if [ $tpm_unowned = 0 ]; then | 88 if [ $tpm_unowned = 0 ]; then |
| (...skipping 21 matching lines...) Expand all Loading... |
| 109 /# NV Index 0xffffffff/ { next } # NV_INDEX_LOCK | 110 /# NV Index 0xffffffff/ { next } # NV_INDEX_LOCK |
| 110 /# NV Index 0x00000000/ { next } # NV_INDEX0 | 111 /# NV Index 0x00000000/ { next } # NV_INDEX0 |
| 111 /# NV Index 0x00000001/ { next } # NV_INDEX_DIR | 112 /# NV Index 0x00000001/ { next } # NV_INDEX_DIR |
| 112 /# NV Index 0x0000f.../ { next } # reserved for TPM use | 113 /# NV Index 0x0000f.../ { next } # reserved for TPM use |
| 113 /# NV Index 0x0001..../ { next } # reserved for TCG WGs | 114 /# NV Index 0x0001..../ { next } # reserved for TCG WGs |
| 114 /# NV Index 0x00001007/ { next } # firmware space index | 115 /# NV Index 0x00001007/ { next } # firmware space index |
| 115 /# NV Index 0x00001008/ { next } # kernel space index | 116 /# NV Index 0x00001008/ { next } # kernel space index |
| 116 /# NV Index / { print $4 } #unexpected space | 117 /# NV Index / { print $4 } #unexpected space |
| 117 EOF | 118 EOF |
| 118 | 119 |
| 120 local index |
| 121 |
| 122 log "trying to make room by freeing one space" |
| 119 ensure_tcsd_is_running | 123 ensure_tcsd_is_running |
| 120 ensure_tpm_is_owned | 124 ensure_tpm_is_owned |
| 121 unexpected_spaces=$($nvtool --list | $awk -f $AWK_PROGRAM) | 125 unexpected_spaces=$($nvtool --list | $awk -f $AWK_PROGRAM) |
| 122 | 126 |
| 123 status=1 | 127 status=1 |
| 124 | 128 |
| 125 if ("$unexpected_spaces" != ""); then | 129 if [ "$unexpected_spaces" != "" ]; then |
| 126 log_tryfix "unexpected spaces: $unexpected_spaces" | 130 log_tryfix "unexpected spaces: $unexpected_spaces" |
| 127 for index in $unexpected_spaces; do | 131 for index in $unexpected_spaces; do |
| 128 if remove_space $index; then | 132 log "trying to remove space $index" |
| 133 if remove_space $(printf "0x%x" $(( $index )) ); then |
| 129 status=0 | 134 status=0 |
| 130 break; | 135 break; |
| 131 fi | 136 fi |
| 132 done | 137 done |
| 133 fi | 138 fi |
| 134 | 139 |
| 135 return $status | 140 return $status |
| 136 } | 141 } |
| 137 | 142 |
| 138 # define_space <index> <size> <permissions> | 143 # define_space <index> <size> <permissions> |
| 139 | 144 |
| 140 define_space () { | 145 define_space () { |
| 141 local index=$1 | 146 local index=$1 |
| 142 local size=$2 | 147 local size=$2 |
| 143 local permissions=$3 | 148 local permissions=$3 |
| 144 # 0xf004 is for testing if there is enough room without side effects. | 149 # 0xf004 is for testing if there is enough room without side effects. |
| 145 local test_space=0xf004 | 150 local test_space=0xf004 |
| 146 local perm_ppwrite=0x1 | 151 local perm_ppwrite=0x1 |
| 147 local enough_room | 152 local enough_room |
| 148 | 153 |
| 149 ensure_tpm_is_unowned | 154 ensure_tpm_is_unowned |
| 150 while true; do | 155 while true; do |
| 156 log "checking for NVRAM room for space with size $size" |
| 151 if $tpmc definespace $test_space $size $perm_ppwrite; then | 157 if $tpmc definespace $test_space $size $perm_ppwrite; then |
| 158 log "there is enough room" |
| 152 enough_room=1 | 159 enough_room=1 |
| 153 break | 160 break |
| 154 else | 161 else |
| 162 log "definespace $test_space $size failed with status $?" |
| 155 if ! make_room; then | 163 if ! make_room; then |
| 156 enough_room=0 | 164 enough_room=0 |
| 157 break | 165 break |
| 158 fi | 166 fi |
| 159 fi | 167 fi |
| 160 done | 168 done |
| 161 | 169 |
| 162 if [ $enough_room -eq 0 ]; then | 170 if [ $enough_room -eq 0 ]; then |
| 163 log "not enough room to define space $index" | 171 log "not enough room to define space $index" |
| 164 return 1 | 172 return 1 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 | 229 |
| 222 # ------------ | 230 # ------------ |
| 223 # MAIN PROGRAM | 231 # MAIN PROGRAM |
| 224 # ------------ | 232 # ------------ |
| 225 | 233 |
| 226 # Set up logging and announce ourselves. | 234 # Set up logging and announce ourselves. |
| 227 | 235 |
| 228 if [ $# = 1 ]; then | 236 if [ $# = 1 ]; then |
| 229 RECOVERY_LOG="$1" | 237 RECOVERY_LOG="$1" |
| 230 /usr/bin/logger "$0 started, output in $RECOVERY_LOG" | 238 /usr/bin/logger "$0 started, output in $RECOVERY_LOG" |
| 231 log "starting" | 239 log "starting $0" |
| 232 else | 240 else |
| 233 /usr/bin/logger "$0 usage error" | 241 /usr/bin/logger "$0 usage error" |
| 234 echo "usage: $0 <log file>" | 242 echo "usage: $0 <log file>" |
| 235 exit 1 | 243 exit 1 |
| 236 fi | 244 fi |
| 237 | 245 |
| 238 # Sanity check: are we executing in a recovery image? | 246 # Sanity check: are we executing in a recovery image? |
| 239 | 247 |
| 240 if [ ! -e $dot_recovery ]; then | 248 if [ ! -e $dot_recovery ]; then |
| 241 quit "not a recovery image" | 249 quit "not a recovery image" |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 log "could not fix firmware space" | 323 log "could not fix firmware space" |
| 316 fix_space 0x1008 0x1 0xd "01 4c 57 52 47 00 00 00 00 00 00 00 00" || \ | 324 fix_space 0x1008 0x1 0xd "01 4c 57 52 47 00 00 00 00 00 00 00 00" || \ |
| 317 log "could not fix kernel space" | 325 log "could not fix kernel space" |
| 318 | 326 |
| 319 # Cleanup: don't leave the tpm owned with the well-known password. | 327 # Cleanup: don't leave the tpm owned with the well-known password. |
| 320 if [ $tpm_owned_with_well_known_password -eq 1 ]; then | 328 if [ $tpm_owned_with_well_known_password -eq 1 ]; then |
| 321 tpm_clear_and_reenable | 329 tpm_clear_and_reenable |
| 322 fi | 330 fi |
| 323 | 331 |
| 324 ensure_tcsd_is_not_running | 332 ensure_tcsd_is_not_running |
| OLD | NEW |