From e67f6300862d939d212d79c4ce5e1249102ddcd3 Mon Sep 17 00:00:00 2001 From: Stefan Haberland Date: Mon, 30 Mar 2020 22:13:06 +0200 Subject: [PATCH] zipl: check for valid ipl parmblock lowcore pointer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The lowcore parmblock pointer is not valid in every case. For example it is invalid for CCW type IPL. To have an indication if the pointer is valid do a diag308 to store the parmblock and check if secure boot is enabled. If it is enabled the lowcore pointer is valid and the ipl report that is needed for secure boot can be found right behind the ipl parmblock. Signed-off-by: Stefan Haberland Reviewed-by: Philipp Rudo Signed-off-by: Jan Höppner --- include/boot/ipl.h | 1 + zipl/boot/stage3.c | 24 ++++++++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/include/boot/ipl.h b/include/boot/ipl.h index 6e6394b8..f8df98fe 100644 --- a/include/boot/ipl.h +++ b/include/boot/ipl.h @@ -18,6 +18,7 @@ #define IPL_RB_COMPONENT_FLAG_SIGNED 0x80 #define IPL_RB_COMPONENT_FLAG_VERIFIED 0x40 +#define IPL_MAX_SUPPORTED_VERSION 0 #define IPL_PARM_BLOCK_VERSION 0x1 /* IPL Types */ diff --git a/zipl/boot/stage3.c b/zipl/boot/stage3.c index e54df4d3..958f9ff7 100644 --- a/zipl/boot/stage3.c +++ b/zipl/boot/stage3.c @@ -28,6 +28,7 @@ static const char *msg_sipl_inval = "Secure boot failure: invalid load address"; static const char *msg_sipl_unverified = "Secure boot failure: unverified load address"; +static const char *msg_sipl_noparm = "Secure boot failure: unable to load ipl parameter"; static inline void __noreturn start_kernel(void) { @@ -56,6 +57,18 @@ static inline void __noreturn start_kernel(void) while (1); } +unsigned int store_ipl_parmblock(struct ipl_pl_hdr *pl_hdr) +{ + int rc; + + rc = diag308(DIAG308_STORE, pl_hdr); + if (rc == DIAG308_RC_OK && + pl_hdr->version <= IPL_MAX_SUPPORTED_VERSION) + return 0; + + return 1; +} + unsigned int is_verified_address(unsigned long image_addr) { @@ -106,12 +119,15 @@ unsigned int secure_boot_enabled() { struct ipl_pl_hdr *pl_hdr; - unsigned long tmp; + unsigned int rc; - tmp = (unsigned long) S390_lowcore.ipl_parmblock_ptr; - pl_hdr = (struct ipl_pl_hdr *) tmp; + pl_hdr = (void *)get_zeroed_page(); + if (!pl_hdr || store_ipl_parmblock(pl_hdr)) + panic(ESECUREBOOT, "%s", msg_sipl_noparm); + rc = !!(pl_hdr->flags & IPL_FLAG_SECURE); + free_page((unsigned long) pl_hdr); - return pl_hdr->flags & IPL_FLAG_SECURE; + return rc; } void start(void)