From c08d151016ab4d62addc2ec8089a756c0d89d583 Mon Sep 17 00:00:00 2001 From: Coiby Xu Date: Wed, 5 Nov 2025 10:14:28 +0800 Subject: [PATCH 5/5] Allow "sudo kdumpctl" for LUKS dump target Some users may run kdumcptl after "sudo su" or use "sudo kdumpctl". And kdump will fail, # sudo kdumcptl restart request_key: Required key not available keyctl_set_timeout: Invalid argument kexec_file_load failed: Required key not available kdump: kexec: failed to load kdump kernel This happens because the LUKS keys is can only be searched (keyctl request) by the process but not by the user and sudo process inherits the session keyring (@s) of the original user (test in the following example), [test@localhost ~]$ sudo keyctl add user testkey testdata @u 711801750 [test@localhost ~]$ sudo grep testkey /proc/keys 2a6d3b96 I--Q--- 1 perm 3f010000 0 0 user testkey: 8 [test@localhost ~]$ sudo keyctl show 711801750 Keyring Unable to dump key: Permission denied The permission "3f010000" means the process has all the permissions but user only has the view permission i.e. "sudo keyctl show/list @u" will list all the keys but "sudo keyctl show KEY_ID" won't work. Automatically use "sudo -i" which will use the session keyring (@s) of the root to support "sudo kdumpctl". Note "sudo -i kexec" is also needed in order for the process to read the keys in the kernel space. Reported-by: Li Tian Signed-off-by: Coiby Xu --- kdumpctl | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/kdumpctl b/kdumpctl index e0aca1a6..cb10f5bd 100755 --- a/kdumpctl +++ b/kdumpctl @@ -737,7 +737,8 @@ function load_kdump_kernel_key() if ! [[ -f /proc/device-tree/ibm,secure-boot ]]; then return fi - + # %.ima keyring is writable to the user, no need to use + # "sudo -i keyctl" keyctl padd asymmetric "" %:.ima < "/usr/share/doc/kernel-keys/$KDUMP_KERNELVER/kernel-signing-ppc.cer" } @@ -760,6 +761,7 @@ load_kdump() return 1 fi + [[ ${KEYCTL_CMD[0]} == sudo ]] && KEXEC="sudo -i $KEXEC" ddebug "$KEXEC ${args[*]}" if $KEXEC "${args[@]}"; then dinfo "kexec: loaded kdump kernel" @@ -1084,6 +1086,9 @@ remove_luks_vol_keys() local _key_line _key_id _key_desc _status=1 # Get all keys from @u keyring and process each line + # sudo process by default only has the permission to list the keys + # stored in user keyring i.e. "sudo keyctl list" can work not + # "sudo keyctl unlink/show" while read -r _key_line; do # Skip header lines and empty lines [[ $_key_line =~ ^[0-9]+: ]] || continue @@ -1100,7 +1105,7 @@ remove_luks_vol_keys() # Check if key description starts with LUKS_KEY_PRFIX if [[ $_key_desc == "$LUKS_KEY_PRFIX"* ]]; then - keyctl unlink "$_key_id" + "${KEYCTL_CMD[@]}" unlink "$_key_id" _status=0 fi done < <(keyctl list @u 2> /dev/null || true) @@ -1142,11 +1147,22 @@ _get_luks_key_by_unlock() return 1 } +# Some users may use "sudo kdumpctl". sudo process by default inherits the +# session keyring (@s) of the original user which means it can't read LUKS keys +# stored in root's user (@u) which is only linked to root's session keyring. +# So use "sudo -i keyctl" and "sudo kexec" automatically in order to be able to +# search and read the LUKS key(s). +KEYCTL_CMD=(keyctl) prepare_luks() { local _key_id _key_des _luks_unlock_cmd declare -a _luks_devs + # Use "sudo -i" to use the root's session keyring to access LUKS keys + if ! keyctl show @s | grep -qs "_uid.0$"; then + KEYCTL_CMD=(sudo -i keyctl) + fi + mapfile -t _luks_devs < <(get_all_kdump_crypt_dev) if [[ ${#_luks_devs[@]} -lt 1 ]]; then @@ -1174,10 +1190,13 @@ prepare_luks() for _devuuid in "${_luks_devs[@]}"; do _key_dir=$LUKS_CONFIGFS/$_devuuid _key_des=$LUKS_KEY_PRFIX$_devuuid - if _key_id=$(keyctl request logon "$_key_des" 2> /dev/null); then + if _key_id=$("${KEYCTL_CMD[@]}" request logon "$_key_des" 2> /dev/null); then ddebug "Succesfully get @u::%logon:$_key_des" elif _get_luks_key_by_unlock "$_devuuid" "$_key_des"; then - _key_id=$(keyctl request logon "$_key_des") + if ! _key_id=$("${KEYCTL_CMD[@]}" request logon "$_key_des"); then + derror "Probably you are using 'sudo kdumpctl' or 'sudo su', please retry with 'sudo -i kdumpctl'" + return 1 + fi ddebug "Succesfully get @u::%logon:$_key_des after cryptsetup" else derror "Failed to get logon key $_key_des. Run 'kdumpctl restart' manually to start kdump." @@ -1185,7 +1204,7 @@ prepare_luks() fi # Let the key expire after 300 seconds - keyctl timeout "$_key_id" 300 + "${KEYCTL_CMD[@]}" timeout "$_key_id" 300 mkdir "$_key_dir" printf "%s" "$_key_des" > "$_key_dir"/description done -- 2.51.1