kdump-lib.sh: fix variable quoting issue

upstream: fedora
resolves: bz2003832
conflict: none

commit 4f01cb1b0a
Author: Kairui Song <kasong@redhat.com>
Date:   Mon Sep 13 01:18:04 2021 +0800

    kdump-lib.sh: fix variable quoting issue

    Fixed quoting issues found by shellcheck, no feature
    change. This should fix many errors when there is space
    in any shell variables.

    And fixed how remove_cmdline_param is being called in prepare_cmdline.
    Kernel parameters can have space like: param="spaces in here". So currently
    remove_cmdline_param is broken since its args always get split by space.
    But prepare_cmdline is expecting remove_cmdline_param to split its args
    by space and passing a list of kernel args separated by space as a whole arg.
    So fix that by using `xargs` to parse and split the args properly, then
    call remove_cmdline_param.

    Following quoting related issues are fixed (check the link
    for example code and what could go wrong):

    https://github.com/koalaman/shellcheck/wiki/SC1007
    https://github.com/koalaman/shellcheck/wiki/SC2046
    https://github.com/koalaman/shellcheck/wiki/SC2053
    https://github.com/koalaman/shellcheck/wiki/SC2060
    https://github.com/koalaman/shellcheck/wiki/SC2068
    https://github.com/koalaman/shellcheck/wiki/SC2086

    Signed-off-by: Kairui Song <kasong@redhat.com>

Signed-off-by: Tao Liu <ltao@redhat.com>
This commit is contained in:
Tao Liu 2021-11-10 10:24:19 +08:00
parent 078307f19f
commit 653edd848c

View File

@ -25,7 +25,7 @@ is_squash_available() {
if [[ -z "$KDUMP_KERNELVER" ]]; then if [[ -z "$KDUMP_KERNELVER" ]]; then
modprobe --dry-run $kmodule &>/dev/null || return 1 modprobe --dry-run $kmodule &>/dev/null || return 1
else else
modprobe -S $KDUMP_KERNELVER --dry-run $kmodule &>/dev/null || return 1 modprobe -S "$KDUMP_KERNELVER" --dry-run $kmodule &>/dev/null || return 1
fi fi
done done
} }
@ -79,10 +79,10 @@ get_user_configured_dump_disk()
local _target local _target
_target=$(kdump_get_conf_val "ext[234]\|xfs\|btrfs\|minix\|raw") _target=$(kdump_get_conf_val "ext[234]\|xfs\|btrfs\|minix\|raw")
[[ -n "$_target" ]] && echo $_target && return [[ -n "$_target" ]] && echo "$_target" && return
_target=$(get_dracut_args_target "$(kdump_get_conf_val "dracut_args")") _target=$(get_dracut_args_target "$(kdump_get_conf_val "dracut_args")")
[[ -b "$_target" ]] && echo $_target [[ -b "$_target" ]] && echo "$_target"
} }
get_block_dump_target() get_block_dump_target()
@ -94,12 +94,12 @@ get_block_dump_target()
fi fi
_target=$(get_user_configured_dump_disk) _target=$(get_user_configured_dump_disk)
[[ -n "$_target" ]] && to_dev_name $_target && return [[ -n "$_target" ]] && to_dev_name "$_target" && return
# Get block device name from local save path # Get block device name from local save path
_path=$(get_save_path) _path=$(get_save_path)
_target=$(get_target_from_path $_path) _target=$(get_target_from_path "$_path")
[[ -b "$_target" ]] && to_dev_name $_target [[ -b "$_target" ]] && to_dev_name "$_target"
} }
is_dump_to_rootfs() is_dump_to_rootfs()
@ -114,7 +114,7 @@ get_failure_action_target()
if is_dump_to_rootfs; then if is_dump_to_rootfs; then
# Get rootfs device name # Get rootfs device name
_target=$(get_root_fs_device) _target=$(get_root_fs_device)
[[ -b "$_target" ]] && to_dev_name $_target && return [[ -b "$_target" ]] && to_dev_name "$_target" && return
# Then, must be nfs root # Then, must be nfs root
echo "nfs" echo "nfs"
fi fi
@ -158,27 +158,27 @@ get_kdump_targets()
# part is the bind mounted directory which quotes by bracket "[]". # part is the bind mounted directory which quotes by bracket "[]".
get_bind_mount_source() get_bind_mount_source()
{ {
local _mnt=$(df $1 | tail -1 | awk '{print $NF}') local _mnt=$(df "$1" | tail -1 | awk '{print $NF}')
local _path=${1#$_mnt} local _path=${1#$_mnt}
local _src=$(get_mount_info SOURCE target $_mnt -f) local _src=$(get_mount_info SOURCE target "$_mnt" -f)
local _opt=$(get_mount_info OPTIONS target $_mnt -f) local _opt=$(get_mount_info OPTIONS target "$_mnt" -f)
local _fstype=$(get_mount_info FSTYPE target $_mnt -f) local _fstype=$(get_mount_info FSTYPE target "$_mnt" -f)
# bind mount in fstab # bind mount in fstab
if [[ -d "$_src" ]] && [[ "$_fstype" = none ]] && (echo "$_opt" | grep -q "\bbind\b"); then if [[ -d "$_src" ]] && [[ "$_fstype" = none ]] && (echo "$_opt" | grep -q "\bbind\b"); then
echo $_src$_path && return echo "$_src$_path" && return
fi fi
# direct mount # direct mount
local _src_nofsroot=$(get_mount_info SOURCE target $_mnt -v -f) local _src_nofsroot=$(get_mount_info SOURCE target "$_mnt" -v -f)
if [[ $_src_nofsroot = $_src ]]; then if [[ $_src_nofsroot = "$_src" ]]; then
echo $_mnt$_path && return echo "$_mnt$_path" && return
fi fi
local _fsroot=${_src#${_src_nofsroot}[} local _fsroot=${_src#${_src_nofsroot}[}
_fsroot=${_fsroot%]} _fsroot=${_fsroot%]}
_mnt=$(get_mount_info TARGET source $_src_nofsroot -f) _mnt=$(get_mount_info TARGET source "$_src_nofsroot" -f)
# for btrfs, _fsroot will also contain the subvol value as well, strip it # for btrfs, _fsroot will also contain the subvol value as well, strip it
if [[ "$_fstype" = btrfs ]]; then if [[ "$_fstype" = btrfs ]]; then
@ -187,19 +187,19 @@ get_bind_mount_source()
_subvol=${_subvol%,*} _subvol=${_subvol%,*}
_fsroot=${_fsroot#$_subvol} _fsroot=${_fsroot#$_subvol}
fi fi
echo $_mnt$_fsroot$_path echo "$_mnt$_fsroot$_path"
} }
get_mntopt_from_target() get_mntopt_from_target()
{ {
get_mount_info OPTIONS source $1 -f get_mount_info OPTIONS source "$1" -f
} }
# Get the path where the target will be mounted in kdump kernel # Get the path where the target will be mounted in kdump kernel
# $1: kdump target device # $1: kdump target device
get_kdump_mntpoint_from_target() get_kdump_mntpoint_from_target()
{ {
local _mntpoint=$(get_mntpoint_from_target $1) local _mntpoint=$(get_mntpoint_from_target "$1")
# mount under /sysroot if dump to root disk or mount under # mount under /sysroot if dump to root disk or mount under
# mount under /kdumproot if dump target is not mounted in first kernel # mount under /kdumproot if dump target is not mounted in first kernel
@ -249,26 +249,26 @@ get_remote_host()
_config_val=${_config_val%:/*} _config_val=${_config_val%:/*}
_config_val=${_config_val#[} _config_val=${_config_val#[}
_config_val=${_config_val%]} _config_val=${_config_val%]}
echo $_config_val echo "$_config_val"
} }
is_hostname() is_hostname()
{ {
local _hostname=$(echo $1 | grep ":") local _hostname=$(echo "$1" | grep ":")
if [[ -n "$_hostname" ]]; then if [[ -n "$_hostname" ]]; then
return 1 return 1
fi fi
echo $1 | grep -q "[a-zA-Z]" echo "$1" | grep -q "[a-zA-Z]"
} }
# Copied from "/etc/sysconfig/network-scripts/network-functions" # Copied from "/etc/sysconfig/network-scripts/network-functions"
get_hwaddr() get_hwaddr()
{ {
if [[ -f "/sys/class/net/${1}/address" ]]; then if [[ -f "/sys/class/net/$1/address" ]]; then
awk '{ print toupper($0) }' < /sys/class/net/${1}/address awk '{ print toupper($0) }' < "/sys/class/net/$1/address"
elif [[ -d "/sys/class/net/${1}" ]]; then elif [[ -d "/sys/class/net/$1" ]]; then
LC_ALL= LANG= ip -o link show ${1} 2>/dev/null | \ LC_ALL="" LANG="" ip -o link show "$1" 2>/dev/null | \
awk '{ print toupper(gensub(/.*link\/[^ ]* ([[:alnum:]:]*).*/, awk '{ print toupper(gensub(/.*link\/[^ ]* ([[:alnum:]:]*).*/,
"\\1", 1)); }' "\\1", 1)); }'
fi fi
@ -484,14 +484,14 @@ remove_cmdline_param()
local cmdline=$1 local cmdline=$1
shift shift
for arg in $@; do for arg in "$@"; do
cmdline=$(echo "$cmdline" | \ cmdline=$(echo "$cmdline" | \
sed -e "s/\b$arg=[^ ]*//g" \ sed -e "s/\b$arg=[^ ]*//g" \
-e "s/^$arg\b//g" \ -e "s/^$arg\b//g" \
-e "s/[[:space:]]$arg\b//g" \ -e "s/[[:space:]]$arg\b//g" \
-e "s/\s\+/ /g") -e "s/\s\+/ /g")
done done
echo $cmdline echo "$cmdline"
} }
# #
@ -522,7 +522,7 @@ append_cmdline()
cmdline="${cmdline} ${2}=${3}" cmdline="${cmdline} ${2}=${3}"
fi fi
echo $cmdline echo "$cmdline"
} }
# This function check iomem and determines if we have more than # This function check iomem and determines if we have more than
@ -554,12 +554,12 @@ is_secure_boot_enforced()
fi fi
# Detect secure boot on x86 and arm64 # Detect secure boot on x86 and arm64
secure_boot_file=$(find /sys/firmware/efi/efivars -name SecureBoot-* 2>/dev/null) secure_boot_file=$(find /sys/firmware/efi/efivars -name "SecureBoot-*" 2>/dev/null)
setup_mode_file=$(find /sys/firmware/efi/efivars -name SetupMode-* 2>/dev/null) setup_mode_file=$(find /sys/firmware/efi/efivars -name "SetupMode-*" 2>/dev/null)
if [[ -f "$secure_boot_file" ]] && [[ -f "$setup_mode_file" ]]; then if [[ -f "$secure_boot_file" ]] && [[ -f "$setup_mode_file" ]]; then
secure_boot_byte=$(hexdump -v -e '/1 "%d\ "' $secure_boot_file|cut -d' ' -f 5) secure_boot_byte=$(hexdump -v -e '/1 "%d\ "' "$secure_boot_file" | cut -d' ' -f 5)
setup_mode_byte=$(hexdump -v -e '/1 "%d\ "' $setup_mode_file|cut -d' ' -f 5) setup_mode_byte=$(hexdump -v -e '/1 "%d\ "' "$setup_mode_file" | cut -d' ' -f 5)
if [[ "$secure_boot_byte" = "1" ]] && [[ "$setup_mode_byte" = "0" ]]; then if [[ "$secure_boot_byte" = "1" ]] && [[ "$setup_mode_byte" = "0" ]]; then
return 0 return 0
@ -589,7 +589,7 @@ prepare_kexec_args()
need_64bit_headers need_64bit_headers
if [[ $? == 1 ]] if [[ $? == 1 ]]
then then
found_elf_args=$(echo $kexec_args | grep elf32-core-headers) found_elf_args=$(echo "$kexec_args" | grep elf32-core-headers)
if [[ -n "$found_elf_args" ]] if [[ -n "$found_elf_args" ]]
then then
dwarn "Warning: elf32-core-headers overrides correct elf64 setting" dwarn "Warning: elf32-core-headers overrides correct elf64 setting"
@ -597,14 +597,14 @@ prepare_kexec_args()
kexec_args="$kexec_args --elf64-core-headers" kexec_args="$kexec_args --elf64-core-headers"
fi fi
else else
found_elf_args=$(echo $kexec_args | grep elf64-core-headers) found_elf_args=$(echo "$kexec_args" | grep elf64-core-headers)
if [[ -z "$found_elf_args" ]] if [[ -z "$found_elf_args" ]]
then then
kexec_args="$kexec_args --elf32-core-headers" kexec_args="$kexec_args --elf32-core-headers"
fi fi
fi fi
fi fi
echo $kexec_args echo "$kexec_args"
} }
# #
@ -636,7 +636,7 @@ prepare_kdump_bootinfo()
for dir in $boot_dirlist; do for dir in $boot_dirlist; do
for img in $boot_imglist; do for img in $boot_imglist; do
if [[ -f "$dir/$img" ]]; then if [[ -f "$dir/$img" ]]; then
KDUMP_KERNEL=$(echo $dir/$img | tr -s '/') KDUMP_KERNEL=$(echo "$dir/$img" | tr -s '/')
break 2 break 2
fi fi
done done
@ -648,7 +648,7 @@ prepare_kdump_bootinfo()
fi fi
# Set KDUMP_BOOTDIR to where kernel image is stored # Set KDUMP_BOOTDIR to where kernel image is stored
KDUMP_BOOTDIR=$(dirname $KDUMP_KERNEL) KDUMP_BOOTDIR=$(dirname "$KDUMP_KERNEL")
# Default initrd should just stay aside of kernel image, try to find it in KDUMP_BOOTDIR # Default initrd should just stay aside of kernel image, try to find it in KDUMP_BOOTDIR
boot_initrdlist="initramfs-$KDUMP_KERNELVER.img initrd" boot_initrdlist="initramfs-$KDUMP_KERNELVER.img initrd"
@ -689,7 +689,7 @@ get_watchdog_drvs()
# device/modalias will return driver of this device # device/modalias will return driver of this device
[[ -f "$_dir/device/modalias" ]] || continue [[ -f "$_dir/device/modalias" ]] || continue
_drv=$(< "$_dir/device/modalias") _drv=$(< "$_dir/device/modalias")
_drv=$(modprobe --set-version "$KDUMP_KERNELVER" -R $_drv 2>/dev/null) _drv=$(modprobe --set-version "$KDUMP_KERNELVER" -R "$_drv" 2>/dev/null)
for i in $_drv; do for i in $_drv; do
if ! [[ " $_wdtdrvs " == *" $i "* ]]; then if ! [[ " $_wdtdrvs " == *" $i "* ]]; then
_wdtdrvs="$_wdtdrvs $i" _wdtdrvs="$_wdtdrvs $i"
@ -697,7 +697,7 @@ get_watchdog_drvs()
done done
done done
echo $_wdtdrvs echo "$_wdtdrvs"
} }
# #
@ -706,7 +706,7 @@ get_watchdog_drvs()
# Store the final result in global $KDUMP_COMMANDLINE. # Store the final result in global $KDUMP_COMMANDLINE.
prepare_cmdline() prepare_cmdline()
{ {
local cmdline id local cmdline id arg
if [[ -z "$1" ]]; then if [[ -z "$1" ]]; then
cmdline=$(</proc/cmdline) cmdline=$(</proc/cmdline)
@ -717,7 +717,9 @@ prepare_cmdline()
# These params should always be removed # These params should always be removed
cmdline=$(remove_cmdline_param "$cmdline" crashkernel panic_on_warn) cmdline=$(remove_cmdline_param "$cmdline" crashkernel panic_on_warn)
# These params can be removed configurably # These params can be removed configurably
cmdline=$(remove_cmdline_param "$cmdline" "$2") while read -r arg; do
cmdline=$(remove_cmdline_param "$cmdline" "$arg")
done <<< "$(echo "$2" | xargs -n 1 echo)"
# Always remove "root=X", as we now explicitly generate all kinds # Always remove "root=X", as we now explicitly generate all kinds
# of dump target mount information including root fs. # of dump target mount information including root fs.
@ -761,20 +763,20 @@ prepare_cmdline()
cmdline=$(remove_cmdline_param "$cmdline" trace_buf_size trace_event) cmdline=$(remove_cmdline_param "$cmdline" trace_buf_size trace_event)
cmdline="${cmdline} trace_buf_size=1" cmdline="${cmdline} trace_buf_size=1"
echo ${cmdline} echo "$cmdline"
} }
#get system memory size in the unit of GB #get system memory size in the unit of GB
get_system_size() get_system_size()
{ {
result=$(grep "System RAM" /proc/iomem | awk -F ":" '{ print $1 }' | tr [:lower:] [:upper:] | paste -sd+) result=$(grep "System RAM" /proc/iomem | awk -F ":" '{ print $1 }' | tr "[:lower:]" "[:upper:]" | paste -sd+)
result="+$result" result="+$result"
# replace '-' with '+0x' and '+' with '-0x' # replace '-' with '+0x' and '+' with '-0x'
sum=$(echo "$result" | sed -e 's/-/K0x/g' -e 's/+/-0x/g' -e 's/K/+/g') sum=$(echo "$result" | sed -e 's/-/K0x/g' -e 's/+/-0x/g' -e 's/K/+/g')
size=$(printf "%d\n" $(($sum))) size=$(printf "%d\n" $(($sum)))
size=$((size / 1024 / 1024 / 1024)) size=$((size / 1024 / 1024 / 1024))
echo $size echo "$size"
} }
get_recommend_size() get_recommend_size()
@ -790,15 +792,15 @@ get_recommend_size()
fi fi
IFS=',' IFS=','
for i in $_ck_cmdline; do for i in $_ck_cmdline; do
end=$(echo $i | awk -F "-" '{ print $2 }' | awk -F ":" '{ print $1 }') end=$(echo "$i" | awk -F "-" '{ print $2 }' | awk -F ":" '{ print $1 }')
recommend=$(echo $i | awk -F "-" '{ print $2 }' | awk -F ":" '{ print $2 }') recommend=$(echo "$i" | awk -F "-" '{ print $2 }' | awk -F ":" '{ print $2 }')
size=${end: : -1} size=${end: : -1}
unit=${end: -1} unit=${end: -1}
if [[ $unit == 'T' ]]; then if [[ $unit == 'T' ]]; then
size=$((size * 1024)) size=$((size * 1024))
fi fi
if [[ $mem_size -lt $size ]]; then if [[ $mem_size -lt $size ]]; then
echo $recommend echo "$recommend"
IFS="$OLDIFS" IFS="$OLDIFS"
return return
fi fi
@ -850,10 +852,10 @@ get_luks_crypt_dev()
{ {
[[ -b /dev/block/$1 ]] || return 1 [[ -b /dev/block/$1 ]] || return 1
local _type=$(eval "$(blkid -u filesystem,crypto -o export -- /dev/block/$1); echo \$TYPE") local _type=$(eval "$(blkid -u filesystem,crypto -o export -- "/dev/block/$1"); echo \$TYPE")
[[ $_type == "crypto_LUKS" ]] && echo $1 [[ $_type == "crypto_LUKS" ]] && echo "$1"
for _x in /sys/dev/block/$1/slaves/*; do for _x in "/sys/dev/block/$1/slaves/"*; do
[[ -f $_x/dev ]] || continue [[ -f $_x/dev ]] || continue
[[ $_x/subsystem -ef /sys/class/block ]] || continue [[ $_x/subsystem -ef /sys/class/block ]] || continue
get_luks_crypt_dev "$(< "$_x/dev")" get_luks_crypt_dev "$(< "$_x/dev")"
@ -883,7 +885,7 @@ get_all_kdump_crypt_dev()
check_vmlinux() check_vmlinux()
{ {
# Use readelf to check if it's a valid ELF # Use readelf to check if it's a valid ELF
readelf -h $1 &>/dev/null || return 1 readelf -h "$1" &>/dev/null || return 1
} }
get_vmlinux_size() get_vmlinux_size()
@ -905,14 +907,14 @@ try_decompress()
# Try to find the header ($1) and decompress from here # Try to find the header ($1) and decompress from here
for pos in $(tr "$1\n$2" "\n$2=" < "$4" | grep -abo "^$2") for pos in $(tr "$1\n$2" "\n$2=" < "$4" | grep -abo "^$2")
do do
if ! type -P $3 > /dev/null; then if ! type -P "$3" > /dev/null; then
ddebug "Signiature detected but '$3' is missing, skip this decompressor" ddebug "Signiature detected but '$3' is missing, skip this decompressor"
break break
fi fi
pos=${pos%%:*} pos=${pos%%:*}
tail -c+$pos "$img" | $3 > $5 2> /dev/null tail "-c+$pos" "$img" | $3 > "$5" 2> /dev/null
if check_vmlinux $5; then if check_vmlinux "$5"; then
ddebug "Kernel is extracted with '$3'" ddebug "Kernel is extracted with '$3'"
return 0 return 0
fi fi
@ -926,22 +928,22 @@ get_kernel_size()
{ {
# Prepare temp files: # Prepare temp files:
local img=$1 tmp=$(mktemp /tmp/vmlinux-XXX) local img=$1 tmp=$(mktemp /tmp/vmlinux-XXX)
trap "rm -f $tmp" 0 trap 'rm -f "$tmp"' 0
# Try to check if it's a vmlinux already # Try to check if it's a vmlinux already
check_vmlinux $img && get_vmlinux_size $img && return 0 check_vmlinux "$img" && get_vmlinux_size "$img" && return 0
# That didn't work, so retry after decompression. # That didn't work, so retry after decompression.
try_decompress '\037\213\010' xy gunzip $img $tmp || \ try_decompress '\037\213\010' xy gunzip "$img" "$tmp" || \
try_decompress '\3757zXZ\000' abcde unxz $img $tmp || \ try_decompress '\3757zXZ\000' abcde unxz "$img" "$tmp" || \
try_decompress 'BZh' xy bunzip2 $img $tmp || \ try_decompress 'BZh' xy bunzip2 "$img" "$tmp" || \
try_decompress '\135\0\0\0' xxx unlzma $img $tmp || \ try_decompress '\135\0\0\0' xxx unlzma "$img" "$tmp" || \
try_decompress '\211\114\132' xy 'lzop -d' $img $tmp || \ try_decompress '\211\114\132' xy 'lzop -d' "$img" "$tmp" || \
try_decompress '\002!L\030' xxx 'lz4 -d' $img $tmp || \ try_decompress '\002!L\030' xxx 'lz4 -d' "$img" "$tmp" || \
try_decompress '(\265/\375' xxx unzstd $img $tmp try_decompress '(\265/\375' xxx unzstd "$img" "$tmp"
# Finally check for uncompressed images or objects: # Finally check for uncompressed images or objects:
[[ $? -eq 0 ]] && get_vmlinux_size $tmp && return 0 [[ $? -eq 0 ]] && get_vmlinux_size "$tmp" && return 0
# Fallback to use iomem # Fallback to use iomem
local _size=0 _seg local _size=0 _seg