Use a file-based lock to prevent closing while being accessed

This commit is contained in:
Peter Cai 2022-11-06 17:48:42 -05:00
parent 7f3834ad14
commit 8832a2aad6
1 changed files with 24 additions and 1 deletions

View File

@ -36,6 +36,17 @@ gocrypt_unique_task_identifier() {
echo "pass-gocrypt-$(sha256sum <<< "$PREFIX" | cut -d ' ' -f 1)"
}
# This file is used as a lock for all access to the encrypted password store
# so that it prevents the auto-close task from unmounting before all operations
# are completed
gocrypt_lock_file_path() {
local path="$XDG_RUNTIME_DIR"
if [ -z "$path" ] || [ ! -d "$path" ]; then
path="/tmp"
fi
echo "$path/$(gocrypt_unique_task_identifier).lck"
}
gocrypt_spawn_close_task() {
which systemd-run > /dev/null || return
which sha256sum > /dev/null || return
@ -45,7 +56,8 @@ gocrypt_spawn_close_task() {
systemctl --user stop "$task_name.timer" > /dev/null 2>1
# Create a new task
systemd-run --user --on-active=$gocrypt_close_timeout --unit="$task_name" /usr/bin/env bash -c \
systemd-run --user --on-active=$gocrypt_close_timeout --unit="$task_name" \
/usr/bin/env flock -x "$(gocrypt_lock_file_path)" /usr/bin/env bash -c \
"fusermount -u '$PREFIX'/'$gocrypt_dec_dir' || fusermount -u -z '$PREFIX'/'$gocrypt_dec_dir'"
echo "Will close the gocryptfs mount after $gocrypt_close_timeout seconds"
@ -151,6 +163,7 @@ gocrypt_close() {
}
gocrypt_delegate() {
# Note: the caller MUST hold the lock for accessing the encrypted password store before calling
gocrypt_open_check
# Delegate command to another `pass` instance that manages what is inside of the mountpoint
PASSWORD_STORE_DIR="$PWD/$gocrypt_dec_dir" "$PROGRAM" "$@"
@ -236,6 +249,13 @@ fi
# cd into the password store prefix
cd "$PREFIX"
# Open the lock file
touch "$(gocrypt_lock_file_path)" || exit 1
exec {lock_fd}< "$(gocrypt_lock_file_path)" || exit 1
# Always take the exclusive lock while any command is running -- to prevent the close task from running at the same time
flock -x $lock_fd
case "$1" in
help)
gocrypt_help
@ -264,3 +284,6 @@ case "$1" in
*)
gocrypt_die "Unknown command $1 for gocrypt"
esac
# Manual unlock; not strictly necessary since exit will also release the lock
flock -u $lock_fd