Remove unused LUKS volume keys from keyring

Resolves: https://issues.redhat.com/browse/RHEL-104940
Conflict: None

commit d7f96424b6dd646803191996a3000af361246f15
Author: Coiby Xu <coxu@redhat.com>
Date:   Wed Sep 17 16:03:22 2025 +0800

    Remove unused LUKS volume keys from keyring

    Currently the LUKS volume keys created via the link-volume-key option
    won't expire. Although the logon key can never leave the kernel and can
    only be used by root, it's safer to remove them from keyring if they are
    no longer used by kdump.

    Signed-off-by: Coiby Xu <coxu@redhat.com>
    Assisted-by: Claude Code

Signed-off-by: Coiby Xu <coxu@redhat.com>
This commit is contained in:
Coiby Xu 2025-10-09 16:52:06 +08:00
parent 4d9c3d6fd1
commit d692a044a1
2 changed files with 118 additions and 1 deletions

View File

@ -1057,6 +1057,35 @@ check_final_action_config()
fi
}
remove_luks_vol_keys()
{
local _key_line _key_id _key_desc _status=1
# Get all keys from @u keyring and process each line
while read -r _key_line; do
# Skip header lines and empty lines
[[ $_key_line =~ ^[0-9]+: ]] || continue
# Extract key ID (first field before colon)
_key_id=${_key_line%%:*}
# Extract key description (everything after "logon: " or "user: ")
if [[ $_key_line =~ logon:\ (.+)$ ]]; then
_key_desc=${BASH_REMATCH[1]}
else
continue
fi
# Check if key description starts with LUKS_KEY_PRFIX
if [[ $_key_desc == "$LUKS_KEY_PRFIX"* ]]; then
keyctl unlink "$_key_id"
_status=0
fi
done < <(keyctl list @u 2> /dev/null || true)
return $_status
}
_get_luks_key_by_unlock()
{
local _devuuid=$1 _key_des=$2
@ -1099,7 +1128,10 @@ prepare_luks()
mapfile -t _luks_devs < <(get_all_kdump_crypt_dev)
if [[ ${#_luks_devs[@]} -lt 1 ]]; then
return
if remove_luks_vol_keys; then
dwarn "Encrypted device not in dump path, please drop the link-volume-key option in $CRYPTTAB_FILE"
fi
return 0
fi
# Currently only x86_64 is supported
@ -1110,6 +1142,7 @@ prepare_luks()
if [[ ! -d $LUKS_CONFIGFS ]]; then
dwarn "$LUKS_CONFIGFS not available, please use a newer kernel or see kexec-kdump-howto.txt to make sure dumping to encrypted target will work."
remove_luks_vol_keys
return 0
fi

View File

@ -87,4 +87,88 @@ luks-007 UUID=uuid-007 none discard,link-volume-key=@u::%logon:${LUKS_KEY_PRFIX}
End
End
Describe "remove_luks_vol_keys()"
Context "when LUKS keys exist in keyring"
It "removes all LUKS keys with correct prefix"
# Arrange - mock keyctl to return keys with LUKS prefix
keyctl() {
case "$1" in
"list")
if [[ "$2" == "@u" ]]; then
cat <<EOF
3 keys in keyring:
464821568: --alsw-v 0 0 logon: ${LUKS_KEY_PRFIX}uuid-001
930415407: --alsw-v 0 0 logon: ${LUKS_KEY_PRFIX}uuid-002
123456789: --alsw-v 0 0 logon: other-key-prefix:uuid-003
EOF
return 0
fi
;;
"unlink")
echo "keyctl unlink $2" >&2
return 0
;;
*)
return 1
;;
esac
}
When call remove_luks_vol_keys
The status should be success
The stderr should include "keyctl unlink 464821568"
The stderr should include "keyctl unlink 930415407"
The stderr should not include "keyctl unlink 123456789"
End
End
Context "when no LUKS keys exist"
It "completes successfully with no matching keys"
# Arrange - return keys but none with LUKS prefix
keyctl() {
case "$1" in
"list")
if [[ "$2" == "@u" ]]; then
cat <<EOF
2 keys in keyring:
123456789: --alsw-v 0 0 logon: other-key-prefix:uuid-003
987654321: --alsw-v 0 0 user: regular-user-key
EOF
return 0
fi
;;
*)
return 1
;;
esac
}
When call remove_luks_vol_keys
The status should be failure
End
It "completes successfully when keyring is empty"
# Arrange
keyctl() {
case "$1" in
"list")
if [[ "$2" == "@u" ]]; then
echo "keyring is empty"
return 0
fi
;;
*)
return 1
;;
esac
}
When call remove_luks_vol_keys
The status should be failure
End
End
End
End