Re: [PATCH 2/2] s390/ipl: Fix NULL deref in dump_reipl without re-IPL parm block

Mikhail Zaslonko <[email protected]>
Newsgroups org.kernel.vger.linux-s390
Message-ID <[email protected]>

On 13-Aug-26 13:06, Vasily Gorbik wrote:
> Unlike kdump, which passes the re-IPL parameter block through os_info,
> the stand-alone dump passes it through the IPL parm block address and
> checksum in lowcore.
> 
> Some IPL types, like HMC FTP boot or QEMU direct kernel boot, might not
> provide an IPL parameter block. In this case reipl_type_init() selects
> IPL_TYPE_UNKNOWN and reipl_block_actual remains NULL. Nevertheless,
> dump_reipl_run() unconditionally dereferences it when preparing the
> lowcore fields. This may happen to work by chance when address zero
> contains readable lowcore data. A zero IPL parameter block address is
> then stored in lowcore, causing the stand-alone dumper to enter disabled
> wait after completing the dump.
> 
> Explicitly store a zero IPL parameter block address and checksum when no
> re-IPL parameter block is available. This does not change the behavior:
> the stand-alone dumper completes the dump and halts, while valid re-IPL
> parameter blocks continue to be handled as before.
> 
> Fixes: 099b76513992 ("[S390] Automatic IPL after dump")
> Signed-off-by: Vasily Gorbik <[email protected]>
> ---
>  arch/s390/kernel/ipl.c | 10 +++++++---
>  1 file changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
> index 7024fc413715..68fdd5616dfe 100644
> --- a/arch/s390/kernel/ipl.c
> +++ b/arch/s390/kernel/ipl.c
> @@ -1929,7 +1929,8 @@ static struct shutdown_action __refdata dump_action = {
>  static void dump_reipl_run(struct shutdown_trigger *trigger)
>  {
>  	struct lowcore *abs_lc;
> -	unsigned int csum;
> +	unsigned long ipib = 0;
> +	unsigned int csum = 0;
>  
>  	/*
>  	 * Set REIPL_CLEAR flag in os_info flags entry indicating
> @@ -1945,9 +1946,12 @@ static void dump_reipl_run(struct shutdown_trigger *trigger)
>  	    reipl_type == IPL_TYPE_UNKNOWN)
>  		os_info_flags |= OS_INFO_FLAG_REIPL_CLEAR;
>  	os_info_entry_add_data(OS_INFO_FLAGS_ENTRY, &os_info_flags, sizeof(os_info_flags));
> -	csum = (__force unsigned int)cksm(reipl_block_actual, reipl_block_actual->hdr.len, 0);
> +	if (reipl_block_actual) {
> +		ipib = __pa(reipl_block_actual);
> +		csum = (__force unsigned int)cksm(reipl_block_actual, reipl_block_actual->hdr.len, 0);
> +	}
>  	abs_lc = get_abs_lowcore();
> -	abs_lc->ipib = __pa(reipl_block_actual);
> +	abs_lc->ipib = ipib;
>  	abs_lc->ipib_checksum = csum;
>  	put_abs_lowcore(abs_lc);
>  	dump_run(trigger);

Reviewed-by: Mikhail Zaslonko <[email protected]>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.