tpmr: Use at_exit for cleanup traps

Multiple traps overwrite each other.  While no tpmr functions have more
than one trap right now, it is fragile, and the quoting is complex due
to double expansion.  Use at_exit to add exit handlers that accumulate
and do not require special quoting.

Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
This commit is contained in:
Jonathon Hall 2023-03-10 17:50:43 -05:00
parent decd45f361
commit 55b3fcfe1a
No known key found for this signature in database
GPG Key ID: 1E9C3CA91AE25114
2 changed files with 42 additions and 8 deletions

View File

@ -226,9 +226,9 @@ tpm2_startsession() {
tpm2 sessionconfig -Q --disable-encrypt "/tmp/$DEC_SESSION_FILE"
}
# Trap EXIT with cleanup_session() to release a TPM2 session and delete the
# Use cleanup_session() with at_exit to release a TPM2 session and delete the
# session file. E.g.:
# trap "cleanup_session '$SESSION_FILE'" EXIT
# at_exit cleanup_session "$SESSION_FILE"
cleanup_session() {
TRACE "Under /bin/tpmr:cleanup_session"
session_file="$1"
@ -243,8 +243,8 @@ cleanup_session() {
}
# Clean up a file by shredding it. No-op if the file wasn't created. Use with
# trap EXIT, e.g.:
# trap "cleanup_shred '$FILE'" EXIT
# at_exit, e.g.:
# at_exit cleanup_shred "$FILE"
cleanup_shred() {
TRACE "Under /bin/tpmr:cleanup_shred"
shred -n 10 -z -u "$1" 2>/dev/null || true
@ -281,7 +281,7 @@ tpm2_seal() {
rm -f "$TRIAL_SESSION" "$AUTH_POLICY"
tpm2 startauthsession -g sha256 -S "$TRIAL_SESSION"
# We have to clean up the session
trap "cleanup_session '$TRIAL_SESSION'" EXIT
at_exit cleanup_session "$TRIAL_SESSION"
# Save the policy hash in case the password policy is not used (we have
# to get this from the last step, whichever it is).
tpm2 policypcr -Q -l "sha256:$pcrl" -f "$pcrf" -S "$TRIAL_SESSION" -L "$AUTH_POLICY"
@ -334,7 +334,7 @@ tpm1_seal() {
tpm_password="$7" # Owner password - will prompt if needed and not empty
sealed_file="$SECRET_DIR/tpm1_seal_sealed.bin"
trap "cleanup_shred '$sealed_file'" EXIT
at_exit cleanup_shred "$sealed_file"
POLICY_ARGS=()
@ -412,7 +412,7 @@ tpm2_unseal() {
POLICY_SESSION=/tmp/unsealfile_policy.session
rm -f "$POLICY_SESSION"
tpm2 startauthsession -Q -g sha256 -S "$POLICY_SESSION" --policy-session
trap "cleanup_session '$POLICY_SESSION'" EXIT
at_exit cleanup_session "$POLICY_SESSION"
# Check the PCR policy
tpm2 policypcr -Q -l "sha256:$pcrl" -S "$POLICY_SESSION"
UNSEAL_PASS_SUFFIX=""
@ -442,7 +442,7 @@ tpm1_unseal() {
# correct either, so just ignore it in TPM1.
sealed_file="$SECRET_DIR/tpm1_unseal_sealed.bin"
trap "cleanup_shred '$sealed_file'" EXIT
at_exit cleanup_shred "$sealed_file"
rm -f "$sealed_file"

View File

@ -576,3 +576,37 @@ generate_random_mac_address()
#Borrowed from https://stackoverflow.com/questions/42660218/bash-generate-random-mac-address-unicast
hexdump -n 6 -ve '1/1 "%.2x "' /dev/urandom | awk -v a="2,6,a,e" -v r="$RANDOM" 'BEGIN{srand(r);}NR==1{split(a,b,",");r=int(rand()*4+1);printf "%s%s:%s:%s:%s:%s:%s\n",substr($1,0,1),b[r],$2,$3,$4,$5,$6}'
}
# Add a command to be invoked at exit. (Note that trap EXIT replaces any
# existing handler.) Commands are invoked in reverse order, so they can be used
# to clean up resources, etc.
# The parameters are all executed as-is and do _not_ require additional quoting
# (unlike trap). E.g.:
# at_exit shred "$file" #<-- file is expanded when calling at_exit, no extra quoting needed
at_exit() {
AT_EXIT_HANDLERS+=("$@") # Command and args
AT_EXIT_HANDLERS+=("$#") # Number of elements in this command
}
# Array of all exit handler command arguments with lengths of each command at
# the end. For example:
# at_exit echo hello
# at_exit echo a b c
# results in:
# AT_EXIT_HANDLERS=(echo hello 2 echo a b c 4)
AT_EXIT_HANDLERS=()
# Each handler is an array AT_EXIT_HANDLER_{i}
run_at_exit_handlers() {
local cmd_pos cmd_len
cmd_pos="${#AT_EXIT_HANDLERS[@]}"
# Silence trace if there are no handlers, this is common and occurs a lot
[ "$cmd_pos" -gt 0 ] && DEBUG "Running at_exit handlers"
while [ "$cmd_pos" -gt 0 ]; do
cmd_pos="$((cmd_pos-1))"
cmd_len="${AT_EXIT_HANDLERS[$cmd_pos]}"
cmd_pos="$((cmd_pos-cmd_len))"
"${AT_EXIT_HANDLERS[@]:$cmd_pos:$cmd_len}"
done
}
trap run_at_exit_handlers EXIT