From 128e5f86feb3add063e4621ac44fde0e23b4eded Mon Sep 17 00:00:00 2001 From: Marc Hartmayer Date: Mon, 10 Nov 2025 16:17:25 +0000 Subject: [PATCH] netboot: Add longer kernel command lines support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since Linux commit 5ecb2da660ab ("s390: support command lines longer than 896 bytes") the s390x kernel supports longer command lines than 896 bytes. The indication of the maximum size is stored in a new field at address 0x10430, older kernels without the support store a value of 0 there so in that case fallback to the old maximum length of 896. In addition, use the checked size as limit to copy in the 'dd' call. This prevents Linux kernel corruption in case the parmline has changed in between. Fixes: https://github.com/ibm-s390-linux/s390-tools/issues/194 Reviewed-by: Jan Höppner Signed-off-by: Marc Hartmayer Signed-off-by: Jan Höppner --- netboot/mk-s390image | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/netboot/mk-s390image b/netboot/mk-s390image index a24da356..19214c0e 100755 --- a/netboot/mk-s390image +++ b/netboot/mk-s390image @@ -21,8 +21,9 @@ # Offsets OFFS_INITRD_START_BYTES=66568 OFFS_INITRD_SIZE_BYTES=66576 +OFFS_COMMANDLINE_MAX_SIZE_BYTES=66608 OFFS_COMMANDLINE_BYTES=66688 -MAX_PARMFILE_SIZE=896 +LEGACY_MAX_PARMFILE_SIZE=896 # Variables cmd=$(basename -- "$0") @@ -87,6 +88,25 @@ dec2be64() printf '%b' "$b" } +max_kernel_cmdline_size() +{ + local __kernel=$1 size v + + size_be="$(od -A n -j "${OFFS_COMMANDLINE_MAX_SIZE_BYTES}" -N 8 -t uL -- "$__kernel")" + # If little endian then swap bytes + if (("$(printf '\1' | od -dAn)" == 1)); then + v="$(printf '%016x0' "$size_be")" + size="0x${v:14:2}${v:12:2}${v:10:2}${v:8:2}${v:6:2}${v:4:2}${v:2:2}${v:0:2}" + else + size="$size_be" + fi + if ((size == 0)); then + size="${LEGACY_MAX_PARMFILE_SIZE}" + fi + # Use arithmetic expression to remove leading and trailing whitespace. + printf '%s' "$((size))" +} + # Do the image build dobuild() { @@ -137,16 +157,17 @@ dobuild() # set cmdline if [ "$parmfile" != "" ] then + max_parmfile_size=$(max_kernel_cmdline_size "$kernel") parmfile_size=$(du -b -L -- "$parmfile" | cut -f1) - if [ "$parmfile_size" -le $MAX_PARMFILE_SIZE ] + if (( parmfile_size <= max_parmfile_size )); then # Clear any previous parameters - dd seek=$OFFS_COMMANDLINE_BYTES bs=1 count=$MAX_PARMFILE_SIZE \ + dd seek=$OFFS_COMMANDLINE_BYTES bs=1 count="$max_parmfile_size" \ if=/dev/zero of="$image" conv=notrunc status=none - dd seek=$OFFS_COMMANDLINE_BYTES bs=1 if="$parmfile" \ - of="$image" conv=notrunc status=none + dd seek=$OFFS_COMMANDLINE_BYTES bs=1 count="$parmfile_size" \ + if="$parmfile" of="$image" conv=notrunc status=none else - echo "$cmd: Size $parmfile_size of $parmfile exceeds command line limit of $MAX_PARMFILE_SIZE" >&2 + echo "$cmd: Size $parmfile_size of $parmfile exceeds command line limit of $max_parmfile_size bytes" >&2 return 1 fi fi