[PATCH v17 24/34] pc-bios/s390-ccw: Add signed component address overlap checks
Zhuoying Cai <[email protected]>
| Newsgroups | gmane.comp.emulators.qemu |
|---|---|
| Message-ID | <[email protected]> |
Add address range tracking and overlap checks to ensure that no component overlaps with a signed component during secure IPL. Signed-off-by: Zhuoying Cai <[email protected]> Reviewed-by: Jared Rossi <[email protected]> Reviewed-by: Matthew Rosato <[email protected]> Reviewed-by: Collin Walling <[email protected]> --- pc-bios/s390-ccw/secure-ipl.c | 19 +++++++++++++++++++ pc-bios/s390-ccw/secure-ipl.h | 10 ++++++++++ 2 files changed, 29 insertions(+) diff --git a/pc-bios/s390-ccw/secure-ipl.c b/pc-bios/s390-ccw/secure-ipl.c index a03105cf5a..fd3455cf67 100644 --- a/pc-bios/s390-ccw/secure-ipl.c +++ b/pc-bios/s390-ccw/secure-ipl.c @@ -193,6 +193,23 @@ static void init_lists(IplDeviceComponentList *comp_list, cert_list->ipl_info_header.len = sizeof(IplInfoBlockHeader); } +static void check_comp_overlap(IplDeviceComponentList *comp_list, + IplDeviceComponentEntry comp_entry) +{ + IplDeviceComponentEntry *comp; + + /* + * Check component's address range does not overlap with any + * signed component's address range. + */ + for_each_rb_entry(comp, comp_list) { + if (comp->flags & S390_IPL_DEV_COMP_FLAG_SC && + intersects(comp->addr, comp->len, comp_entry.addr, comp_entry.len)) { + zipl_secure_error("Component addresses overlap"); + } + } +} + static int zipl_load_signature(ComponentEntry *entry, uint64_t sig) { if (entry->compdat.sig_info.format != DER_SIGNATURE_FORMAT) { @@ -294,6 +311,8 @@ int zipl_run_secure(ComponentEntry **entry_ptr, const uint8_t *tmp_sec, comp_entry.addr = comp_addr; comp_entry.len = (uint64_t)comp_len; + check_comp_overlap(comp_list, comp_entry); + /* no signature present (unsigned component) */ if (!sig_entry.len) { comp_list_add(comp_list, comp_entry); diff --git a/pc-bios/s390-ccw/secure-ipl.h b/pc-bios/s390-ccw/secure-ipl.h index b5a871a799..d495dd5d04 100644 --- a/pc-bios/s390-ccw/secure-ipl.h +++ b/pc-bios/s390-ccw/secure-ipl.h @@ -116,4 +116,14 @@ static inline bool verify_signature(IplDeviceComponentEntry comp_entry, return false; } +static inline bool intersects(uint64_t addr0, uint64_t size0, + uint64_t addr1, uint64_t size1) +{ + if (addr1 > addr0) { + return addr1 - addr0 < size0; + } + + return addr0 - addr1 < size1; +} + #endif /* _PC_BIOS_S390_CCW_SECURE_IPL_H */ -- 2.55.0