Skip to content

Commit c08d151

Browse files
committed
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 <[email protected]> Signed-off-by: Coiby Xu <[email protected]>
1 parent fe2891d commit c08d151

File tree

1 file changed

+24
-5
lines changed

1 file changed

+24
-5
lines changed

kdumpctl

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -737,7 +737,8 @@ function load_kdump_kernel_key()
737737
if ! [[ -f /proc/device-tree/ibm,secure-boot ]]; then
738738
return
739739
fi
740-
740+
# %.ima keyring is writable to the user, no need to use
741+
# "sudo -i keyctl"
741742
keyctl padd asymmetric "" %:.ima < "/usr/share/doc/kernel-keys/$KDUMP_KERNELVER/kernel-signing-ppc.cer"
742743
}
743744

@@ -760,6 +761,7 @@ load_kdump()
760761
return 1
761762
fi
762763

764+
[[ ${KEYCTL_CMD[0]} == sudo ]] && KEXEC="sudo -i $KEXEC"
763765
ddebug "$KEXEC ${args[*]}"
764766
if $KEXEC "${args[@]}"; then
765767
dinfo "kexec: loaded kdump kernel"
@@ -1084,6 +1086,9 @@ remove_luks_vol_keys()
10841086
local _key_line _key_id _key_desc _status=1
10851087

10861088
# Get all keys from @u keyring and process each line
1089+
# sudo process by default only has the permission to list the keys
1090+
# stored in user keyring i.e. "sudo keyctl list" can work not
1091+
# "sudo keyctl unlink/show"
10871092
while read -r _key_line; do
10881093
# Skip header lines and empty lines
10891094
[[ $_key_line =~ ^[0-9]+: ]] || continue
@@ -1100,7 +1105,7 @@ remove_luks_vol_keys()
11001105

11011106
# Check if key description starts with LUKS_KEY_PRFIX
11021107
if [[ $_key_desc == "$LUKS_KEY_PRFIX"* ]]; then
1103-
keyctl unlink "$_key_id"
1108+
"${KEYCTL_CMD[@]}" unlink "$_key_id"
11041109
_status=0
11051110
fi
11061111
done < <(keyctl list @u 2> /dev/null || true)
@@ -1142,11 +1147,22 @@ _get_luks_key_by_unlock()
11421147
return 1
11431148
}
11441149

1150+
# Some users may use "sudo kdumpctl". sudo process by default inherits the
1151+
# session keyring (@s) of the original user which means it can't read LUKS keys
1152+
# stored in root's user (@u) which is only linked to root's session keyring.
1153+
# So use "sudo -i keyctl" and "sudo kexec" automatically in order to be able to
1154+
# search and read the LUKS key(s).
1155+
KEYCTL_CMD=(keyctl)
11451156
prepare_luks()
11461157
{
11471158
local _key_id _key_des _luks_unlock_cmd
11481159
declare -a _luks_devs
11491160

1161+
# Use "sudo -i" to use the root's session keyring to access LUKS keys
1162+
if ! keyctl show @s | grep -qs "_uid.0$"; then
1163+
KEYCTL_CMD=(sudo -i keyctl)
1164+
fi
1165+
11501166
mapfile -t _luks_devs < <(get_all_kdump_crypt_dev)
11511167

11521168
if [[ ${#_luks_devs[@]} -lt 1 ]]; then
@@ -1174,18 +1190,21 @@ prepare_luks()
11741190
for _devuuid in "${_luks_devs[@]}"; do
11751191
_key_dir=$LUKS_CONFIGFS/$_devuuid
11761192
_key_des=$LUKS_KEY_PRFIX$_devuuid
1177-
if _key_id=$(keyctl request logon "$_key_des" 2> /dev/null); then
1193+
if _key_id=$("${KEYCTL_CMD[@]}" request logon "$_key_des" 2> /dev/null); then
11781194
ddebug "Succesfully get @u::%logon:$_key_des"
11791195
elif _get_luks_key_by_unlock "$_devuuid" "$_key_des"; then
1180-
_key_id=$(keyctl request logon "$_key_des")
1196+
if ! _key_id=$("${KEYCTL_CMD[@]}" request logon "$_key_des"); then
1197+
derror "Probably you are using 'sudo kdumpctl' or 'sudo su', please retry with 'sudo -i kdumpctl'"
1198+
return 1
1199+
fi
11811200
ddebug "Succesfully get @u::%logon:$_key_des after cryptsetup"
11821201
else
11831202
derror "Failed to get logon key $_key_des. Run 'kdumpctl restart' manually to start kdump."
11841203
return 1
11851204
fi
11861205

11871206
# Let the key expire after 300 seconds
1188-
keyctl timeout "$_key_id" 300
1207+
"${KEYCTL_CMD[@]}" timeout "$_key_id" 300
11891208
mkdir "$_key_dir"
11901209
printf "%s" "$_key_des" > "$_key_dir"/description
11911210
done

0 commit comments

Comments
 (0)