diff options
| author | Stephen Cprek <smcprek@us.ibm.com> | 2017-10-31 13:01:30 -0500 |
|---|---|---|
| committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2017-11-19 15:54:51 -0500 |
| commit | 81279c1d146d8ee920494c7817cdd72f165dd373 (patch) | |
| tree | d616d0914823c8c25592e8276e0610ba1c9d2a28 /src/usr/util | |
| parent | 63a026113332464fc3bcc73369ba35bfe8f62b6f (diff) | |
| download | talos-hostboot-81279c1d146d8ee920494c7817cdd72f165dd373.tar.gz talos-hostboot-81279c1d146d8ee920494c7817cdd72f165dd373.zip | |
Secure Boot: Fix lid load from HB reserved memory issues at runtime
- Force all PNOR sections we load from HB rserved memory to be secure
Only exception is the RINGOVD section, in which we use a fake header
- Add fake header when Secureboot compiled out or a section is never
signed as there is no secure header preserved in virtual memory
RTC: 171708
RTC: 180063
Change-Id: Ibbbd7be24ee7b199e73451c63b2c2d1f86a2c2d8
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/49020
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Reviewed-by: Marshall J. Wilks <mjwilks@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Michael Baiocchi <mbaiocch@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/util')
| -rw-r--r-- | src/usr/util/runtime/utillidmgr_rt.C | 72 | ||||
| -rw-r--r-- | src/usr/util/utillidpnor.C | 58 |
2 files changed, 83 insertions, 47 deletions
diff --git a/src/usr/util/runtime/utillidmgr_rt.C b/src/usr/util/runtime/utillidmgr_rt.C index 52490cac1..0e45de3f0 100644 --- a/src/usr/util/runtime/utillidmgr_rt.C +++ b/src/usr/util/runtime/utillidmgr_rt.C @@ -35,6 +35,7 @@ #include <trace/interface.H> #include "../utilbase.H" #include <util/utillidpnor.H> +#include <pnor/pnor_reasoncodes.H> UtilLidMgr::UtilLidMgr(uint32_t i_lidId) : iv_isLidInPnor(false), iv_lidBuffer(nullptr), iv_lidSize(0), @@ -142,13 +143,14 @@ errlHndl_t UtilLidMgr::loadLid() { if(iv_isLidInHbResvMem) { + const auto pnorSectionId = Util::getLidPnorSection( + static_cast<Util::LidId>(iv_lidId)); + UTIL_FT("UtilLidMgr::loadLid> iv_isLidInHbResvMem=true"); iv_lidBuffer = reinterpret_cast<void*>(g_hostInterfaces-> get_reserved_mem( - PNOR::SectionIdToString( - Util::getLidPnorSection( - static_cast<Util::LidId>(iv_lidId))), - 0)); + PNOR::SectionIdToString(pnorSectionId), + 0)); // If nullptr returned, set size to 0 to indicate we could not find // the lid in HB resv memory @@ -160,30 +162,48 @@ errlHndl_t UtilLidMgr::loadLid() else { UTIL_FT("UtilLidMgr::loadLid - resv mem section found"); - // If section is secure, adjust size and buffer pointer - // TODO: RTC:180063 if getSectionInfo is modified to not support - // secure sections, then need a different - // method. - if(iv_lidPnorInfo.secure) - { - UTIL_FT("UtilLidMgr::loadLid - resv mem section is secure"); - // Build a container header object to parse protected size - SECUREBOOT::ContainerHeader l_conHdr(iv_lidBuffer); - iv_lidSize = l_conHdr.payloadTextSize(); - - // Increment by page size to not expose secure header - iv_lidBuffer = static_cast<uint8_t*>(iv_lidBuffer) + - PAGESIZE; - } - else + + // Ensure Section has a Secure Header + if (!PNOR::cmpSecurebootMagicNumber( + reinterpret_cast<uint8_t*>(iv_lidBuffer))) { - // If no secure header, just use PNOR size - // NOTE: Unsigned sections with sha512Version have already - // skipped over the header and decreased size while - // parsing the PNOR TOC - iv_lidSize = iv_lidPnorInfo.size; - UTIL_FT("UtilLidMgr::loadLid - iv_lidSize=%d", iv_lidSize ); + UTIL_FT(ERR_MRK"UtilLidMgr::loadLid: currently don't support " + "a reserved memory area without a secure header. Section = %s", + PNOR::SectionIdToString(pnorSectionId)); + + uint64_t l_actualBytes = 0; + memcpy(&l_actualBytes, + iv_lidBuffer, + sizeof(ROM_MAGIC_NUMBER)); + + /*@ + * @errortype ERRL_SEV_INFORMATIONAL + * @moduleid Util::UTIL_LIDMGR_RT + * @reasoncode PNOR::RC_BAD_SECURE_MAGIC_NUM + * @userdata1 Section attempting to be loaded + * @userdata2 First 4 bytes of vaddr + * @devdesc Error loading lid from reserved memory without secure header + * @custdesc Firmware Error + */ + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_INFORMATIONAL, + Util::UTIL_LIDMGR_RT, + PNOR::RC_BAD_SECURE_MAGIC_NUM, + pnorSectionId, + l_actualBytes, + true/*SW Error*/); + break; } + + UTIL_FT("UtilLidMgr::loadLid - resv mem section has secure header"); + + // Build a container header object to parse protected size + SECUREBOOT::ContainerHeader l_conHdr(iv_lidBuffer); + iv_lidSize = l_conHdr.payloadTextSize(); + + // Increment by page size to not expose secure header + iv_lidBuffer = static_cast<uint8_t*>(iv_lidBuffer) + + PAGESIZE; } } else if(iv_isLidInVFS) diff --git a/src/usr/util/utillidpnor.C b/src/usr/util/utillidpnor.C index de69964a2..25c90c73e 100644 --- a/src/usr/util/utillidpnor.C +++ b/src/usr/util/utillidpnor.C @@ -26,15 +26,15 @@ #include <util/utillidmgr.H> #include <util/utillidpnor.H> #include <config.h> -#ifdef CONFIG_SECUREBOOT #include <pnor/pnorif.H> #include <errl/errlmanager.H> -#endif #include <utility> #include <map> #include <trace/interface.H> #include "utilbase.H" +#include <initservice/initserviceif.H> +#include <pnor/pnor_reasoncodes.H> namespace Util { @@ -100,7 +100,7 @@ PNOR::SectionId getLidPnorSection(const LidId i_lid) bool UtilLidMgr::getLidPnorSectionInfo(uint32_t i_lidId, PNOR::SectionInfo_t &o_lidPnorInfo) { - errlHndl_t l_err = NULL; + errlHndl_t l_err = nullptr; bool l_lidInPnor = false; // Search if a lid id maps to pnor section @@ -110,30 +110,58 @@ bool UtilLidMgr::getLidPnorSectionInfo(uint32_t i_lidId, // LidToPnor will return INVALID_SECITON if no mapping found if (l_secId == PNOR::INVALID_SECTION) { - UTIL_FT("UtilLidMgr::getLidPnorSection lid 0x%X not in PNOR", i_lidId); + UTIL_FT("UtilLidMgr::getLidPnorSectionInfo lid 0x%X not in PNOR", i_lidId); o_lidPnorInfo.id = PNOR::INVALID_SECTION; } // A mapping was found else { + // PNOR section is optional or lid is not in PNOR, so just delete error + // During IPL + // PNOR section may be optional + // In Runtime + // FSP - prohibit access to PNOR + // OP - PNOR access of pre-verifed HB reserved memory sections not allowed. +#ifdef __HOSTBOOT_RUNTIME + // Do not allow PNOR access at runtime on FSP based machines + if(INITSERVICE::spBaseServicesEnabled()) + { + break; + } +#endif l_err = PNOR::getSectionInfo(l_secId, o_lidPnorInfo); - // Section is optional or lid is not in PNOR, so just delete error - if (l_err) + if (l_err && +#ifdef __HOSTBOOT_RUNTIME + (l_err->reasonCode() == PNOR::RC_RTPNOR_INVALID_SECTION) +#else + (l_err->reasonCode() == PNOR::RC_INVALID_SECTION) +#endif + ) { o_lidPnorInfo.id = PNOR::INVALID_SECTION; delete l_err; - l_err = NULL; + l_err = nullptr; + UTIL_FT("UtilLidMgr::getLidPnorSectionInfo Lid 0x%X ignore getSectionInfo error", + i_lidId); + break; + } + else if (l_err) + { + UTIL_FT(ERR_MRK"UtilLidMgr::getLidPnorSectionInfo Lid 0x%X getSectionInfo error shutting down rc=0x%08X", + l_err->reasonCode()); + errlCommit(l_err, UTIL_COMP_ID); + break; } else { l_lidInPnor = true; - UTIL_FT("UtilLidMgr::getLidPnorSection Lid 0x%X in PNOR", i_lidId); + UTIL_FT("UtilLidMgr::getLidPnorSectionInfo Lid 0x%X in PNOR", i_lidId); #ifdef CONFIG_SECUREBOOT #ifndef __HOSTBOOT_RUNTIME // The lid could be securely signed in PNOR if(o_lidPnorInfo.secure) { - UTIL_FT("UtilLidMgr::getLidPnorSection verify Lid in PNOR"); + UTIL_FT("UtilLidMgr::getLidPnorSectionInfo verify Lid in PNOR"); // Load the secure section l_err = loadSecureSection(l_secId); @@ -157,18 +185,6 @@ bool UtilLidMgr::getLidPnorSectionInfo(uint32_t i_lidId, } #endif #endif - -#ifdef __HOSTBOOT_RUNTIME - //use this check for HBRT due to secure lid load setting vaddr - //to zero -- which causes isSectionEmpty to segfault - if( !o_lidPnorInfo.vaddr ) - { - UTIL_FT("UtilLidMgr::getLidPnorSection PNOR section %s is empty or secure", - PNOR::SectionIdToString(l_secId)); - l_lidInPnor = false; - break; - } -#endif } } } while(0); |

