From 34dbdc49d0d14933c317be2815302d0d558c5924 Mon Sep 17 00:00:00 2001 From: Stephen Cprek Date: Fri, 15 Dec 2017 10:24:02 -0600 Subject: Convert asserts to error logs where it makes sense Change-Id: Idd15e39cc6be44c0865f13503bfa4482d77fcf0d RTC:181899 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/51042 Tested-by: Jenkins Server Reviewed-by: Michael Baiocchi Tested-by: Jenkins OP Build CI Tested-by: Jenkins OP HW Tested-by: FSP CI Jenkins Reviewed-by: Martin Gloff Reviewed-by: Nicholas E. Bofferding Reviewed-by: Daniel M. Crowell --- src/include/usr/pnor/pnor_reasoncodes.H | 5 + src/include/usr/runtime/runtime_reasoncodes.H | 10 ++ src/include/usr/secureboot/header.H | 6 +- src/include/usr/secureboot/secure_reasoncodes.H | 8 + src/include/usr/secureboot/service.H | 5 +- src/include/usr/util/util_reasoncodes.H | 2 + src/include/usr/util/utillidmgr.H | 54 ++++--- src/usr/errl/parser/genErrlParsers.pl | 1 + src/usr/pnor/pnorrp.C | 28 +++- src/usr/pnor/spnorrp.C | 190 ++++++++++++++++++---- src/usr/pnor/spnorrp.H | 5 +- src/usr/runtime/populate_hbruntime.C | 199 ++++++++++++++++++++++-- src/usr/runtime/preverifiedlidmgr.C | 85 +++++++++- src/usr/secureboot/base/header.C | 40 ++++- src/usr/secureboot/base/service.C | 73 ++++++++- src/usr/secureboot/base/settings.C | 83 ++++++++-- src/usr/util/runtime/utillidmgr_rt.C | 39 ++++- src/usr/util/utillidmgr.C | 78 ++++++++-- src/usr/util/utillidpnor.C | 25 ++- 19 files changed, 807 insertions(+), 129 deletions(-) diff --git a/src/include/usr/pnor/pnor_reasoncodes.H b/src/include/usr/pnor/pnor_reasoncodes.H index e9e98f9c5..589337a3b 100644 --- a/src/include/usr/pnor/pnor_reasoncodes.H +++ b/src/include/usr/pnor/pnor_reasoncodes.H @@ -182,6 +182,11 @@ namespace PNOR RC_NOT_A_LOADED_SECTION = PNOR_COMP_ID | 0x35, RC_NOT_A_SUPPORTED_SECTION = PNOR_COMP_ID | 0x36, RC_SECURE_UNLOAD_DISALLOWED = PNOR_COMP_ID | 0x37, + RC_SECURE_TOTAL_SIZE_INVAL = PNOR_COMP_ID | 0x38, + RC_SECURE_VADDR_MISMATCH = PNOR_COMP_ID | 0x39, + RC_SECURE_SIZE_MISMATCH = PNOR_COMP_ID | 0x3A, + RC_NOT_PAGE_ALIGNED = PNOR_COMP_ID | 0x3B, + RC_SECURE_PRO_SIZE_MISMATCH = PNOR_COMP_ID | 0x3C, //@fixme-RTC:131607-Temporary value to allow HWSV compile //termination_rc diff --git a/src/include/usr/runtime/runtime_reasoncodes.H b/src/include/usr/runtime/runtime_reasoncodes.H index 8bf056675..4ce07c0c2 100644 --- a/src/include/usr/runtime/runtime_reasoncodes.H +++ b/src/include/usr/runtime/runtime_reasoncodes.H @@ -45,6 +45,8 @@ namespace RUNTIME MOD_HDATSERVICE_MAPREGION = 0x0B, /**< hdatservice.C */ MOD_HDATSERVICE_GETINSTANCECOUNT = 0x0C, /**< hdatservice.C */ MOD_HDATSERVICE_GETANDCHECKTUPLE = 0x0D, /**< hdatservice.C */ + MOD_PREVERLIDMGR_LOAD_FROM_PNOR = 0x0E, /** preverifiedlidmgr.C **/ + MOD_PREVERLIDMGR_LOAD_IMAGE = 0x0F, /** preverifiedlidmgr.C **/ // customize_attrs_for_payload.C MOD_CUST_COMP_NON_PHYP_RT_TARGET = 0x12, @@ -104,6 +106,14 @@ namespace RUNTIME RC_EXCEEDED_MEMORY = RUNTIME_COMP_ID | 0x27, RC_UNABLE_TO_PIN_ATTR_MEM = RUNTIME_COMP_ID | 0x28, RC_UNABLE_TO_UNPIN_ATTR_MEM = RUNTIME_COMP_ID | 0x29, + RC_TPM_HDAT_OUT_OF_SPACE = RUNTIME_COMP_ID | 0x2A, + RC_TPM_HDAT_ID_MISMATCH = RUNTIME_COMP_ID | 0x2B, + RC_TPM_HDAT_EYE_CATCH_MISMATCH = RUNTIME_COMP_ID | 0x2C, + RC_TPM_MISSING_PROC = RUNTIME_COMP_ID | 0x2D, + RC_TPM_HDAT_BAD_VERSION = RUNTIME_COMP_ID | 0x2E, + RC_TPM_HDAT_BAD_NUM_I2C = RUNTIME_COMP_ID | 0x2F, + RC_INVALID_LID = RUNTIME_COMP_ID | 0x30, + RC_PREVER_INVALID_SIZE = RUNTIME_COMP_ID | 0x31, }; enum UserDetailsTypes diff --git a/src/include/usr/secureboot/header.H b/src/include/usr/secureboot/header.H index eff1f6769..259d98467 100644 --- a/src/include/usr/secureboot/header.H +++ b/src/include/usr/secureboot/header.H @@ -28,6 +28,8 @@ #include #include #include +#include +#include /** @file header.H * @@ -64,9 +66,9 @@ namespace SECUREBOOT * area preserved across the bootloader to HBB handoff to * support extending HBB measurements to TPM * - * @warning Asserts if header is already cached (code bug) + * @return Error handle if error; otherwise nullptr */ - void loadHeader(); + errlHndl_t loadHeader(); /** * @brief Return pointer to base image (HBB) header. diff --git a/src/include/usr/secureboot/secure_reasoncodes.H b/src/include/usr/secureboot/secure_reasoncodes.H index 21c195b77..49d42e15f 100644 --- a/src/include/usr/secureboot/secure_reasoncodes.H +++ b/src/include/usr/secureboot/secure_reasoncodes.H @@ -44,6 +44,9 @@ namespace SECUREBOOT MOD_SECURE_CONT_HDR_PARSE = 0x0A, MOD_SECURE_CONT_HDR_CPY_INC = 0x0B, MOD_SECURE_CONT_VALIDATE = 0x0C, + MOD_SECURE_SET_SBE_SECURE_MODE = 0x0D, + MOD_SECURE_GET_ALL_SEC_REGS = 0x0E, + MOD_SECURE_LOAD_HEADER = 0x0F, }; enum SECUREReasonCode @@ -61,6 +64,11 @@ namespace SECUREBOOT RC_SECROM_INVALID = SECURE_COMP_ID | 0x0B, RC_CONT_HDR_NO_SPACE = SECURE_COMP_ID | 0x0C, RC_CONT_HDR_INVALID = SECURE_COMP_ID | 0x0D, + RC_SBE_INVALID_SEC_MODE = SECURE_COMP_ID | 0x0E, + RC_DEVICE_WRITE_ERR = SECURE_COMP_ID | 0x0F, + RC_PROC_NOT_SCOMABLE = SECURE_COMP_ID | 0x10, + RC_DEVICE_READ_ERR = SECURE_COMP_ID | 0x11, + RC_INVALID_BASE_HEADER = SECURE_COMP_ID | 0x12, // Reason codes 0xA0 - 0xEF reserved for trustedboot_reasoncodes.H }; diff --git a/src/include/usr/secureboot/service.H b/src/include/usr/secureboot/service.H index dc1fd5a78..7d8953cde 100644 --- a/src/include/usr/secureboot/service.H +++ b/src/include/usr/secureboot/service.H @@ -347,8 +347,11 @@ namespace SECUREBOOT * a value of 0 if SBE should check for security disable * requests and 1 if not. All other values are not * allowed and will be rejected via an assert. + * + * @return errlHndl_t Error log handle; nullptr if success, pointer to + * valid error log otherwise. */ - void setSbeSecurityMode(uint8_t i_sbeSecurityMode); + errlHndl_t setSbeSecurityMode(uint8_t i_sbeSecurityMode); } diff --git a/src/include/usr/util/util_reasoncodes.H b/src/include/usr/util/util_reasoncodes.H index 2b43b6757..587943bdd 100644 --- a/src/include/usr/util/util_reasoncodes.H +++ b/src/include/usr/util/util_reasoncodes.H @@ -51,6 +51,7 @@ namespace Util UTIL_MCL_REL_MEM = 0x11, // MasterContainerLidMgr::releaseMem UTIL_MCL_PROCESS_COMP = 0x12, // MasterContainerLidMgr::processComponent UTIL_MOD_GET_OBUS_PLL_BUCKET = 0x14, // UtilCommonAttr::getObusPllBucket + UTIL_LIDMGR_CSTOR = 0x15, // UtilLidMgr::UtilLidMgr }; enum ReasonCode @@ -81,6 +82,7 @@ namespace Util UTIL_MCL_SIZE_MISMATCH = UTIL_COMP_ID | 0x18, UTIL_ERC_NO_FREQ_LIST = UTIL_COMP_ID | 0x1A, UTIL_ERC_NO_MATCHING_FREQ = UTIL_COMP_ID | 0x1B, + UTIL_LIDMGR_INVAL_LID_REQUEST = UTIL_COMP_ID | 0x1C, }; }; diff --git a/src/include/usr/util/utillidmgr.H b/src/include/usr/util/utillidmgr.H index c2ac2d9a0..a80f67876 100644 --- a/src/include/usr/util/utillidmgr.H +++ b/src/include/usr/util/utillidmgr.H @@ -83,6 +83,7 @@ class UtilLidMgr * @par Detailed Description * Ensures member variables are initialized to sane values. * Sets the initial LID ID. + * Note will shutdown if error occurs during updateLid and not Runtime * * @param[in] i_lidId * LID ID. @@ -111,8 +112,8 @@ class UtilLidMgr * LID ID. * * @return errlHndl_t - * return errl == NULL -> success - * return errl != NULL -> failure + * return errl == nullptr -> success + * return errl != nullptr -> failure */ errlHndl_t setLidId(uint32_t i_lidId); @@ -127,8 +128,8 @@ class UtilLidMgr * Size of the LID in bytes. * * @return errlHndl_t - * return errl == NULL -> success - * return errl != NULL -> failure + * return errl == nullptr -> success + * return errl != nullptr -> failure */ errlHndl_t getLidSize(size_t& o_lidSize); @@ -150,8 +151,8 @@ class UtilLidMgr * for LID. * * @return errlHndl_t - * return errl == NULL -> success - * return errl != NULL -> failure + * return errl == nullptr -> success + * return errl != nullptr -> failure */ errlHndl_t getLid(void* i_dest, size_t i_destSize); @@ -173,8 +174,8 @@ class UtilLidMgr * * * @return errlHndl_t - * return errl == NULL -> success - * return errl != NULL -> failure + * return errl == nullptr -> success + * return errl != nullptr -> failure */ errlHndl_t getStoredLidImage(void*& o_pLidImage, size_t& o_lidImageSize); @@ -187,8 +188,8 @@ class UtilLidMgr * Clears variables associated with storing the image. * * @return errlHndl_t - * return errl == NULL -> success - * return errl != NULL -> failure + * return errl == nullptr -> success + * return errl != nullptr -> failure */ errlHndl_t releaseLidImage(void); @@ -202,7 +203,7 @@ class UtilLidMgr */ inline const void* getLidVirtAddr() const { - const void* l_addr = NULL; + const void* l_addr = nullptr; // Get pointer to PNOR vaddr if (iv_isLidInPnor) { @@ -239,8 +240,11 @@ class UtilLidMgr * * @param[in] i_lidId * LID ID. + * @return errlHndl_t + * return errl == nullptr -> success + * return errl != nullptr -> failure */ - void updateLid(uint32_t i_lidId); + errlHndl_t updateLid(uint32_t i_lidId); /** * @brief performs object cleanup when a new lidId is set @@ -272,8 +276,8 @@ class UtilLidMgr * Indicates image was found in PNOR * * @return errlHndl_t - * return errl == NULL -> success - * return errl != NULL -> failure + * return errl == nullptr -> success + * return errl != nullptr -> failure */ errlHndl_t getLidSizePnor(size_t& o_lidSize, bool& o_imgInPnor); @@ -302,8 +306,8 @@ class UtilLidMgr * Indicates image was found in PNOR * * @return errlHndl_t - * return errl == NULL -> success - * return errl != NULL -> failure + * return errl == nullptr -> success + * return errl != nullptr -> failure */ errlHndl_t getLidPnor(void* i_dest, size_t i_destSize, @@ -335,8 +339,8 @@ class UtilLidMgr * the mutex. * * @return errlHndl_t - * return errl == NULL -> success - * return errl != NULL -> failure + * return errl == nullptr -> success + * return errl != nullptr -> failure */ errlHndl_t createMsgQueue(); @@ -370,8 +374,8 @@ class UtilLidMgr * the fsp. * * @return errlHndl_t - * return errl == NULL -> success - * return errl != NULL -> failure + * return errl == nullptr -> success + * return errl != nullptr -> failure */ errlHndl_t sendMboxMessage( MBOX_MSG_TYPE i_type, msg_t * i_msg ); @@ -437,11 +441,15 @@ class UtilLidMgr * @param[in] i_lidId - lid id to search for * @param[out] o_lidPnorInfo - pnor section info associated with the lid * if it exists in pnor + * @param[out] o_isLidInPnor - True if lid is in a section, false otherwise * - * @return bool - True if lid is in a section, false otherwise + * @return errlHndl_t + * return errl == nullptr -> success + * return errl != nullptr -> failure */ - bool getLidPnorSectionInfo(uint32_t i_lidId, - PNOR::SectionInfo_t &o_lidPnorInfo); + errlHndl_t getLidPnorSectionInfo(uint32_t i_lidId, + PNOR::SectionInfo_t &o_lidPnorInfo, + bool &o_isLidInPnor); /** * @brief LID fileName */ diff --git a/src/usr/errl/parser/genErrlParsers.pl b/src/usr/errl/parser/genErrlParsers.pl index e1bf5b3eb..e0da36c07 100755 --- a/src/usr/errl/parser/genErrlParsers.pl +++ b/src/usr/errl/parser/genErrlParsers.pl @@ -472,6 +472,7 @@ foreach my $file (@filesToParse) # * @userdata1 i_opType # * @userdata2 addr # * @devdesc Invalid Operation type. + # * @custdec Firmware Error # */ # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= while (my $line = ) diff --git a/src/usr/pnor/pnorrp.C b/src/usr/pnor/pnorrp.C index a874d3735..f596401e9 100644 --- a/src/usr/pnor/pnorrp.C +++ b/src/usr/pnor/pnorrp.C @@ -528,7 +528,33 @@ errlHndl_t PnorRP::getSectionInfo( PNOR::SectionId i_section, break; } payloadTextSize = l_conHdr.payloadTextSize(); - assert(payloadTextSize > 0,"Non-zero payload text size expected."); + if ( payloadTextSize <= 0) + { + TRACFCOMP(g_trac_pnor, ERR_MRK"PnorRP::getSectionInfo: non-zero protected payload text size expected for section %s", + o_info.name); + + /*@ + * @errortype + * @moduleid PNOR::MOD_PNORRP_GETSECTIONINFO + * @reasoncode PNOR::RC_SECTION_SIZE_IS_ZERO + * @userdata1 PNOR section + * @userdata2 Section's secure flag + * @devdesc Protected Payload Size is 0 + * @custdesc Platform security problem detected + */ + l_errhdl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + PNOR::MOD_PNORRP_GETSECTIONINFO, + PNOR::RC_SECTION_SIZE_IS_ZERO, + i_section, + o_info.secure, + true /*Add HB SW Callout*/); + l_errhdl->collectTrace(PNOR_COMP_NAME); + l_errhdl->collectTrace(SECURE_COMP_NAME); + // set the return section to our invalid data + id = PNOR::INVALID_SECTION; + break; + } // skip secure header for secure sections at this point in time o_info.vaddr += PAGESIZE; diff --git a/src/usr/pnor/spnorrp.C b/src/usr/pnor/spnorrp.C index 29dd6de64..72a03d026 100644 --- a/src/usr/pnor/spnorrp.C +++ b/src/usr/pnor/spnorrp.C @@ -363,8 +363,33 @@ uint64_t SPnorRP::verifySections(SectionId i_id, l_info.size += PAGESIZE; // add a page to size to account for the header // it's a coding error if l_info.vaddr is not in secure space - assert(l_info.vaddr >= SBASE_VADDR, "Virtual address for section %s is" - " not in secure space. Bad ptr=0x%X", l_info.name, l_info.vaddr); + if (l_info.vaddr < SBASE_VADDR) + { + TRACFCOMP(g_trac_pnor,ERR_MRK"SPnorRP::verifySections Virtual address for section %s is not in secure space. Virtual address=0x%llX", + l_info.name, l_info.vaddr); + /*@ + * @errortype + * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid PNOR::MOD_SPNORRP_VERIFYSECTIONS + * @reasoncode PNOR::RC_SECURE_VADDR_MISMATCH + * @userdata1 PNOR section + * @userdata2 PNOR section virtual address + * @devdesc Virtual address of PNOR section is not in Secure Space + * @custdesc Platform Security Error + */ + l_errhdl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + PNOR::MOD_SPNORRP_VERIFYSECTIONS, + PNOR::RC_SECURE_VADDR_MISMATCH, + TO_UINT64(i_id), + l_info.vaddr, + true); + SECUREBOOT::addSecureUserDetailsToErrlog(l_errhdl); + l_errhdl->collectTrace(PNOR_COMP_NAME); + l_errhdl->collectTrace(SECURE_COMP_NAME); + break; + } + // Note: A pointer to virtual memory in one PNOR space can be converted // to a pointer to any of the other two PNOR spaces and visa versa. @@ -433,20 +458,65 @@ uint64_t SPnorRP::verifySections(SectionId i_id, TRACFCOMP(g_trac_pnor, "SPnorRP::verifySections " "Total container size = 0x%.16llX", l_totalContainerSize); - assert(l_totalContainerSize >= PAGESIZE + - + l_info.secureProtectedPayloadSize, - "For section %s, total container size (%d) was less than header " - "size (4096) + payload text size (%d)", - l_info.name, - l_totalContainerSize, - l_info.secureProtectedPayloadSize); - - assert(l_info.size >= l_totalContainerSize, - "For section %s, logical section size (%d) was less than total " - "container size (%d)", - l_info.name, - l_info.size, - l_totalContainerSize); + if (l_totalContainerSize < + (PAGESIZE + l_info.secureProtectedPayloadSize)) + { + TRACFCOMP(g_trac_pnor,ERR_MRK"SPnorRP::verifySections For section %s, total container size (%d) was less than header " + "size (4096) + payload text size (%d)", + l_info.name, + l_totalContainerSize, + l_info.secureProtectedPayloadSize) + /*@ + * @errortype + * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid PNOR::MOD_SPNORRP_VERIFYSECTIONS + * @reasoncode PNOR::RC_SECURE_TOTAL_SIZE_INVAL + * @userdata1 PNOR section + * @userdata2 Protected Payload Size plus Header Size + * @devdesc Total Container Size smaller than Protected Payload and Header size + * @custdesc Failure in security subsystem + */ + l_errhdl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + PNOR::MOD_SPNORRP_VERIFYSECTIONS, + PNOR::RC_SECURE_TOTAL_SIZE_INVAL, + TO_UINT64(i_id), + PAGESIZE + l_info.secureProtectedPayloadSize, + true); + SECUREBOOT::addSecureUserDetailsToErrlog(l_errhdl); + l_errhdl->collectTrace(PNOR_COMP_NAME); + l_errhdl->collectTrace(SECURE_COMP_NAME); + break; + } + + if (l_info.size < l_totalContainerSize) + { + TRACFCOMP(g_trac_pnor,ERR_MRK"SPnorRP::verifySections For section %s, logical section size (%d) was less than total container size (%d)", + l_info.name, + l_info.size, + l_totalContainerSize); + /*@ + * @errortype + * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid PNOR::MOD_SPNORRP_VERIFYSECTIONS + * @reasoncode PNOR::RC_SECURE_SIZE_MISMATCH + * @userdata1 PNOR section + * @userdata2 Total Container Size + * @devdesc PNOR section size smaller than total container size + * @custdesc Failure in security subsystem + */ + l_errhdl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + PNOR::MOD_SPNORRP_VERIFYSECTIONS, + PNOR::RC_SECURE_SIZE_MISMATCH, + TO_UINT64(i_id), + l_totalContainerSize, + true); + SECUREBOOT::addSecureUserDetailsToErrlog(l_errhdl); + l_errhdl->collectTrace(PNOR_COMP_NAME); + l_errhdl->collectTrace(SECURE_COMP_NAME); + break; + } TRACDCOMP(g_trac_pnor,"SPnorRP::verifySections did memcpy"); TRACDBIN(g_trac_pnor,"SPnorRP::verifySections temp mem now: ", @@ -505,7 +575,35 @@ uint64_t SPnorRP::verifySections(SectionId i_id, // store the payload text size in the section load record // Note: the text size we get back is now trusted io_rec->textSize = l_conHdr.payloadTextSize(); - assert(io_rec->textSize == l_info.secureProtectedPayloadSize); + if (io_rec->textSize != l_info.secureProtectedPayloadSize) + { + TRACFCOMP(g_trac_pnor,ERR_MRK"SPnorRP::verifySections For section %s, verified protected size (%d) does not equal unverified size parsed by pnorrp (%d)", + l_info.name, + io_rec->textSize , + l_info.secureProtectedPayloadSize); + /*@ + * @errortype + * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid PNOR::MOD_SPNORRP_VERIFYSECTIONS + * @reasoncode PNOR::RC_SECURE_PRO_SIZE_MISMATCH + * @userdata1 PNOR section + * @userdata2 Protected Payload Size + * @devdesc Verified Protected Payload size does not match what was parsed by PnorRp + * @custdesc Failure in security subsystem + */ + l_errhdl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + PNOR::MOD_SPNORRP_VERIFYSECTIONS, + PNOR::RC_SECURE_PRO_SIZE_MISMATCH, + TO_UINT64(i_id), + l_info.secureProtectedPayloadSize, + true); + SECUREBOOT::addSecureUserDetailsToErrlog(l_errhdl); + l_errhdl->collectTrace(PNOR_COMP_NAME); + l_errhdl->collectTrace(SECURE_COMP_NAME); + break; + } + // Size of data loaded into Secure PnorRP vaddr space (Includes Header) size_t l_protectedSizeWithHdr = PAGESIZE + io_rec->textSize; TRACFCOMP(g_trac_pnor, "SPnorRP::verifySections Total Protected size with Header = 0x%.16llX", @@ -562,13 +660,33 @@ uint64_t SPnorRP::verifySections(SectionId i_id, unprotectedPayloadSize, l_info.name); - // Split the mod math out of the assert as the trace would not - // display otherwise. - bool l_onPageBoundary = !(io_rec->textSize % PAGESIZE); - assert( l_onPageBoundary, "For section %s, payloadTextSize does " - "not fall on a page boundary and there is an unprotected " - "payload", - l_info.name); + if ((io_rec->textSize % PAGESIZE)) + { + TRACFCOMP(g_trac_pnor,ERR_MRK"SPnorRP::verifySections For section %s, payloadTextSize does not fall on a page boundary and there is an unprotected payload", + l_info.name); + /*@ + * @errortype + * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid PNOR::MOD_SPNORRP_VERIFYSECTIONS + * @reasoncode PNOR::RC_NOT_PAGE_ALIGNED + * @userdata1 PNOR section + * @userdata2 Protected Payload Size + * @devdesc Protected Payload Size not Page aligned + * @custdesc Failure in security subsystem + */ + l_errhdl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + PNOR::MOD_SPNORRP_VERIFYSECTIONS, + PNOR::RC_NOT_PAGE_ALIGNED, + TO_UINT64(i_id), + io_rec->textSize, + true); + SECUREBOOT::addSecureUserDetailsToErrlog(l_errhdl); + l_errhdl->collectTrace(PNOR_COMP_NAME); + l_errhdl->collectTrace(SECURE_COMP_NAME); + break; + } + l_errhdl = setPermission(io_rec->secAddr + l_protectedSizeWithHdr, unprotectedPayloadSize, @@ -1144,16 +1262,28 @@ errlHndl_t PNOR::unloadSecureSection(const SectionId i_section) return loadUnloadSecureSection(i_section, PNOR::MSG_UNLOAD_SECTION); } -void SPnorRP::processLabOverride( +errlHndl_t SPnorRP::processLabOverride( const sb_flags_t& i_flags) const { + errlHndl_t l_errl = nullptr; + + do{ // Secure boot sbe security mode values are inverted with respect to the // lab override flag for the same logical meaning uint8_t securityMode = !(i_flags.hw_lab_override); - SECUREBOOT::setSbeSecurityMode(securityMode); + l_errl = SECUREBOOT::setSbeSecurityMode(securityMode); + if(l_errl) + { + TRACFCOMP(g_trac_pnor,ERR_MRK"SPnorRP::processLabOverride - lab security override policy failed"); + break; + } + TRACFCOMP(g_trac_pnor,INFO_MRK "Set lab security override policy to %s.", securityMode ? "*NO* override" : "override if requested"); + } while(0); + + return l_errl; } errlHndl_t SPnorRP::processFwKeyIndicators( @@ -1162,11 +1292,17 @@ errlHndl_t SPnorRP::processFwKeyIndicators( { errlHndl_t pError = nullptr; + do { if(i_sectionId == PNOR::SBE_IPL) { auto const * const headerFlags = i_header.sb_flags(); - processLabOverride(*headerFlags); + pError = processLabOverride(*headerFlags); + if (pError) + { + break; + } } + } while(0); return pError; } diff --git a/src/usr/pnor/spnorrp.H b/src/usr/pnor/spnorrp.H index 1734c96f8..11da539ef 100644 --- a/src/usr/pnor/spnorrp.H +++ b/src/usr/pnor/spnorrp.H @@ -242,8 +242,11 @@ class SPnorRP * the security settings. * * @param[in] i_flags Various flags read from the secure header + * + * @return errlHndl_t Error log handle; nullptr if success, pointer to + * valid error log otherwise. */ - void processLabOverride( + errlHndl_t processLabOverride( const sb_flags_t& i_flags) const; /** diff --git a/src/usr/runtime/populate_hbruntime.C b/src/usr/runtime/populate_hbruntime.C index ed23522d2..e22e4fa04 100644 --- a/src/usr/runtime/populate_hbruntime.C +++ b/src/usr/runtime/populate_hbruntime.C @@ -175,6 +175,7 @@ errlHndl_t mapPhysAddr(uint64_t i_addr, i_addr, i_size, true); + l_elog->collectTrace(RUNTIME_COMP_NAME); } return l_elog; @@ -196,7 +197,7 @@ errlHndl_t unmapVirtAddr(uint64_t i_addr) * @moduleid RUNTIME::MOD_UNMAP_VIRT_ADDR * @reasoncode RUNTIME::RC_UNMAP_FAIL * @userdata1 Virtual address we are trying to unmap - * + * @userdata2 0 * @devdesc Error unmapping a virtual memory map * @custdesc Kernel failed to unmap memory */ @@ -205,7 +206,9 @@ errlHndl_t unmapVirtAddr(uint64_t i_addr) RUNTIME::MOD_UNMAP_VIRT_ADDR, RUNTIME::RC_UNMAP_FAIL, i_addr, + 0, true); + l_elog->collectTrace(RUNTIME_COMP_NAME); } return l_elog; @@ -433,6 +436,7 @@ errlHndl_t fill_RsvMem_hbData(uint64_t & io_start_address, l_totalSizeAligned, io_size, true); + l_elog->collectTrace(RUNTIME_COMP_NAME); break; } @@ -1332,18 +1336,97 @@ errlHndl_t populate_TpmInfoByNode() // make sure we have enough room auto const l_tpmDataCalculatedMax = HDAT::hdatTpmDataCalcMaxSize(); - assert(l_dataSizeMax >= l_tpmDataCalculatedMax, - "Bug! The TPM data hdat section doesn't have enough space"); + if(l_dataSizeMax < l_tpmDataCalculatedMax) + { + + TRACFCOMP( g_trac_runtime, ERR_MRK "populate_TpmInfoByNode: The TPM data hdat section doesn't have enough space"); + + /*@ + * @errortype + * @severity ERRL_SEV_UNRECOVERABLE + * @moduleid RUNTIME::MOD_POPULATE_TPMINFOBYNODE + * @reasoncode RUNTIME::RC_TPM_HDAT_OUT_OF_SPACE + * @userdata1 Size of hdat data struct + * @userdata2 Max size of hdat data struct + * @devdesc The TPM data hdat section doesn't have enough space + * @custdesc Platform security problem detected + */ + l_elog = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + RUNTIME::MOD_POPULATE_TPMINFOBYNODE, + RUNTIME::RC_TPM_HDAT_OUT_OF_SPACE, + l_dataSizeMax, + l_tpmDataCalculatedMax, + true); + l_elog->collectTrace(RUNTIME_COMP_NAME); + break; + } // check that hdat structure format and eye catch were filled out - assert(l_hdatTpmData->hdatHdr.hdatStructId == HDAT::HDAT_HDIF_STRUCT_ID, - "Bug! The TPM data hdat struct format value doesn't match"); + if(l_hdatTpmData->hdatHdr.hdatStructId != HDAT::HDAT_HDIF_STRUCT_ID) + { + TRACFCOMP( g_trac_runtime, ERR_MRK "populate_TpmInfoByNode: The TPM data hdat struct format value doesn't match"); + + /*@ + * @errortype + * @severity ERRL_SEV_UNRECOVERABLE + * @moduleid RUNTIME::MOD_POPULATE_TPMINFOBYNODE + * @reasoncode RUNTIME::RC_TPM_HDAT_ID_MISMATCH + * @userdata1 hdat struct format value + * @userdata2 Expected hdat struct format value + * @devdesc TPM data hdat struct format value doesn't match + * @custdesc Platform security problem detected + */ + l_elog = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + RUNTIME::MOD_POPULATE_TPMINFOBYNODE, + RUNTIME::RC_TPM_HDAT_ID_MISMATCH, + l_hdatTpmData->hdatHdr.hdatStructId, + HDAT::HDAT_HDIF_STRUCT_ID, + true); + l_elog->collectTrace(RUNTIME_COMP_NAME); + break; + } auto l_eyeCatchLen = strlen(HDAT::g_hdatTpmDataEyeCatch); - assert(memcmp(l_hdatTpmData->hdatHdr.hdatStructName, - HDAT::g_hdatTpmDataEyeCatch, - l_eyeCatchLen)==0, - "Bug! The TPM data hdat struct name eye catcher doesn't match"); + if(memcmp(l_hdatTpmData->hdatHdr.hdatStructName, + HDAT::g_hdatTpmDataEyeCatch, + l_eyeCatchLen) != 0) + { + + // Convert char strings to uin64_t for errorlogs + uint64_t l_eyeCatch = 0; + memcpy(&l_eyeCatch, + l_hdatTpmData->hdatHdr.hdatStructName, + strnlen(l_hdatTpmData->hdatHdr.hdatStructName,sizeof(uint64_t))); + uint64_t l_expectedEyeCatch = 0; + memcpy(&l_expectedEyeCatch, + HDAT::g_hdatTpmDataEyeCatch, + strnlen(HDAT::g_hdatTpmDataEyeCatch, sizeof(uint64_t))); + + TRACFCOMP( g_trac_runtime, ERR_MRK "populate_TpmInfoByNode: The TPM data hdat struct name eye catcher (0x%X) doesn't match expected value (0x%X", + l_eyeCatch, l_expectedEyeCatch); + + /*@ + * @errortype + * @severity ERRL_SEV_UNRECOVERABLE + * @moduleid RUNTIME::MOD_POPULATE_TPMINFOBYNODE + * @reasoncode RUNTIME::RC_TPM_HDAT_EYE_CATCH_MISMATCH + * @userdata1 hdat struct name eye catcher + * @userdata2 Expected hdat eye catch + * @devdesc TPM data hdat struct name eye catcher doesn't match + * @custdesc Platform security problem detected + */ + l_elog = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + RUNTIME::MOD_POPULATE_TPMINFOBYNODE, + RUNTIME::RC_TPM_HDAT_EYE_CATCH_MISMATCH, + l_eyeCatch, + l_expectedEyeCatch, + true); + l_elog->collectTrace(RUNTIME_COMP_NAME); + break; + } l_hdatTpmData->hdatHdr.hdatInstance = HDAT::TpmDataInstance; l_hdatTpmData->hdatHdr.hdatVersion = HDAT::TpmDataVersion; @@ -1414,7 +1497,31 @@ errlHndl_t populate_TpmInfoByNode() return hasSameI2cMaster(t); }); - assert(itr != l_procList.end(), "Bug! TPM must have a processor."); + if(itr == l_procList.end()) + { + TRACFCOMP( g_trac_runtime, ERR_MRK "populate_TpmInfoByNode: TPM does not have a processor."); + + /*@ + * @errortype + * @severity ERRL_SEV_UNRECOVERABLE + * @moduleid RUNTIME::MOD_POPULATE_TPMINFOBYNODE + * @reasoncode RUNTIME::RC_TPM_MISSING_PROC + * @userdata1 Number of processors + * @userdata2 0 + * @devdesc TPM does not have a processor + * @custdesc Platform security problem detected + */ + l_elog = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + RUNTIME::MOD_POPULATE_TPMINFOBYNODE, + RUNTIME::RC_TPM_MISSING_PROC, + l_procList.size(), + 0, + true); + l_elog->collectTrace(RUNTIME_COMP_NAME); + break; + } + auto l_proc = *itr; l_tpmInstInfo->hdatChipId = l_proc->getAttr< @@ -1498,6 +1605,10 @@ errlHndl_t populate_TpmInfoByNode() // Note: We don't advance the current offset, because the size of the // DRTM event log is zero } + if (l_elog) + { + break; + } // populate second part of pointer pair for secure boot TPM info l_hdatTpmData->hdatSbTpmInfo.hdatSize = l_currOffset - l_sbTpmInfoStart; @@ -1578,9 +1689,32 @@ errlHndl_t populate_TpmInfoByNode() auto l_pcrd = reinterpret_cast(l_pcrdAddr); // Check the version of the PCRD section header - assert(l_pcrd->hdatHdr.hdatVersion >= HDAT::TpmDataMinRqrdPcrdVersion, - "Bad PCRD section version 0x%X - must be 0x1 or greater", - l_pcrd->hdatHdr.hdatVersion); + if(l_pcrd->hdatHdr.hdatVersion < HDAT::TpmDataMinRqrdPcrdVersion) + { + TRACFCOMP( g_trac_runtime, ERR_MRK "populate_TpmInfoByNode: Bad PCRD section version 0x%X - must be 0x%X or greater", + l_pcrd->hdatHdr.hdatVersion, + HDAT::TpmDataMinRqrdPcrdVersion); + + /*@ + * @errortype + * @severity ERRL_SEV_UNRECOVERABLE + * @moduleid RUNTIME::MOD_POPULATE_TPMINFOBYNODE + * @reasoncode RUNTIME::RC_TPM_HDAT_BAD_VERSION + * @userdata1 hdat version + * @userdata2 Expected support version + * @devdesc Bad PCRD section version + * @custdesc Platform security problem detected + */ + l_elog = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + RUNTIME::MOD_POPULATE_TPMINFOBYNODE, + RUNTIME::RC_TPM_HDAT_BAD_VERSION, + l_pcrd->hdatHdr.hdatVersion, + HDAT::TpmDataMinRqrdPcrdVersion, + true); + l_elog->collectTrace(RUNTIME_COMP_NAME); + break; + } // Get offset for the i2c array header auto i2cAryOff = @@ -1598,9 +1732,31 @@ errlHndl_t populate_TpmInfoByNode() reinterpret_cast(l_pcrdAddr + i2cAryOff); // make sure the array count is within reasonable limits - assert(l_hostI2cPcrdHdrPtr->hdatArrayCnt <= HDAT_PCRD_MAX_I2C_DEV, - "HDAT PCRD reported more than the max number of i2c devices! Count:%d", - l_hostI2cPcrdHdrPtr->hdatArrayCnt); + if(l_hostI2cPcrdHdrPtr->hdatArrayCnt > HDAT_PCRD_MAX_I2C_DEV) + { + TRACFCOMP( g_trac_runtime, ERR_MRK "populate_TpmInfoByNode: HDAT PCRD reported more than the max number of i2c devices! Count:%d", + l_hostI2cPcrdHdrPtr->hdatArrayCnt); + + /*@ + * @errortype + * @severity ERRL_SEV_UNRECOVERABLE + * @moduleid RUNTIME::MOD_POPULATE_TPMINFOBYNODE + * @reasoncode RUNTIME::RC_TPM_HDAT_BAD_NUM_I2C + * @userdata1 hdat array count + * @userdata2 max number of i2c devices + * @devdesc HDAT PCRD reported more than the max number of i2c devices + * @custdesc Platform security problem detected + */ + l_elog = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + RUNTIME::MOD_POPULATE_TPMINFOBYNODE, + RUNTIME::RC_TPM_HDAT_BAD_NUM_I2C, + l_hostI2cPcrdHdrPtr->hdatArrayCnt, + HDAT_PCRD_MAX_I2C_DEV, + true); + l_elog->collectTrace(RUNTIME_COMP_NAME); + break; + } // Get the pointer to the first element in the i2c array // This is the address of the header plus the offset given in the header @@ -1649,7 +1805,7 @@ errlHndl_t populate_TpmInfoByNode() l_linkId, 0, true); - + err->collectTrace(RUNTIME_COMP_NAME); SECUREBOOT::handleSecurebootFailure(err); assert(false,"Bug! handleSecurebootFailure shouldn't return!"); @@ -1728,6 +1884,7 @@ errlHndl_t populate_TpmInfoByNode() l_i2cDev->hdatI2cLinkId, 0, true); + err->collectTrace(RUNTIME_COMP_NAME); ERRORLOG::errlCommit(err, RUNTIME_COMP_ID); } else @@ -1757,6 +1914,7 @@ errlHndl_t populate_TpmInfoByNode() l_i2cDev->hdatI2cLinkId, 0, true); + err->collectTrace(RUNTIME_COMP_NAME); ERRORLOG::errlCommit(err, RUNTIME_COMP_ID); } else // found a match @@ -1769,6 +1927,10 @@ errlHndl_t populate_TpmInfoByNode() } // for each link ID in the current PCRD instance } // for each instance + if (l_elog) + { + break; + } if (!l_i2cTargetList.empty()) { @@ -1816,6 +1978,7 @@ errlHndl_t populate_TpmInfoByNode() ), TARGETING::get_huid(i2cDevItr->masterChip), true); + err->collectTrace(RUNTIME_COMP_NAME); ERRORLOG::errlCommit(err, RUNTIME_COMP_ID); } } @@ -2116,6 +2279,7 @@ errlHndl_t persistent_rwAttrRuntimeCheck( void ) l_rc, rc, true /* Add HB Software Callout */); + l_err->collectTrace(RUNTIME_COMP_NAME); } else { @@ -2156,6 +2320,7 @@ errlHndl_t persistent_rwAttrRuntimeCheck( void ) l_rc, rc, true /* Add HB Software Callout */); + l_err->collectTrace(RUNTIME_COMP_NAME); } } diff --git a/src/usr/runtime/preverifiedlidmgr.C b/src/usr/runtime/preverifiedlidmgr.C index e4ec082ac..e28e56af7 100644 --- a/src/usr/runtime/preverifiedlidmgr.C +++ b/src/usr/runtime/preverifiedlidmgr.C @@ -38,6 +38,7 @@ #include #include #include +#include extern trace_desc_t *g_trac_runtime; @@ -189,7 +190,31 @@ errlHndl_t PreVerifiedLidMgr::_loadFromPnor(const PNOR::SectionId i_sec, auto l_lids = Util::getPnorSecLidIds(i_sec); TRACDCOMP( g_trac_runtime, "PreVerifiedLidMgr::_loadFromPnor - getPnorSecLidIds lid = 0x%X, containerLid = 0x%X", l_lids.lid, l_lids.containerLid); - assert(l_lids.lid != Util::INVALID_LIDID,"Pnor Section = %s not associated with any Lids", PNOR::SectionIdToString(i_sec)); + if(l_lids.lid == Util::INVALID_LIDID) + { + TRACFCOMP( g_trac_runtime, ERR_MRK "PreVerifiedLidMgr::_loadFromPnor - Pnor Section = %s not associated with any Lids", + PNOR::SectionIdToString(i_sec)); + + /*@ + * @errortype + * @severity ERRL_SEV_UNRECOVERABLE + * @moduleid RUNTIME::MOD_PREVERLIDMGR_LOAD_FROM_PNOR + * @reasoncode RUNTIME::RC_INVALID_LID + * @userdata1 PNOR section + * @userdata2 Lid id mapped from PNOR section + * @devdesc Trying to load invalid lid + * @custdesc Platform security problem detected + */ + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + RUNTIME::MOD_PREVERLIDMGR_LOAD_FROM_PNOR, + RUNTIME::RC_INVALID_LID, + i_sec, + l_lids.lid, + true); + l_errl->collectTrace(RUNTIME_COMP_NAME); + break; + } // Only load if not previously done. if( isLidLoaded(l_lids.containerLid) && isLidLoaded(l_lids.lid) ) @@ -229,9 +254,36 @@ errlHndl_t PreVerifiedLidMgr::_loadFromPnor(const PNOR::SectionId i_sec, if ( (l_lids.lid != Util::INVALID_LIDID) && !isLidLoaded(l_lids.lid)) { + // Ensure there is content besides the header and that the size is + // valid + if(i_size <= PAGE_SIZE) + { + TRACFCOMP( g_trac_runtime, ERR_MRK "PreVerifiedLidMgr::_loadFromPnor - PNOR Section %s size 0x%X is not greater than the header size 0x%X, thus missing actual content to pre-verify", + PNOR::SectionIdToString(i_sec), i_size, PAGE_SIZE); + + /*@ + * @errortype + * @severity ERRL_SEV_UNRECOVERABLE + * @moduleid RUNTIME::MOD_PREVERLIDMGR_LOAD_FROM_PNOR + * @reasoncode RUNTIME::RC_PREVER_INVALID_SIZE + * @userdata1 PNOR section + * @userdata2 Size of section including header + * @devdesc No content after Section header or size was parsed from secure header incorrectly. + * @custdesc Platform security problem detected + */ + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + RUNTIME::MOD_PREVERLIDMGR_LOAD_FROM_PNOR, + RUNTIME::RC_PREVER_INVALID_SIZE, + i_sec, + i_size, + true); + l_errl->collectTrace(RUNTIME_COMP_NAME); + break; + } + char l_lidStr[Util::lidIdStrLength] {}; snprintf (l_lidStr, Util::lidIdStrLength, "%08X",l_lids.lid); - assert(i_size > PAGE_SIZE, "PreVerifiedLidMgr::_loadFromPnor - caller did not include size of header for total size"); l_errl = RUNTIME::setNextHbRsvMemEntry(HDAT::RHB_TYPE_VERIFIED_LIDS, cv_pResvMemInfo->rangeId, cv_pResvMemInfo->curAddr+PAGE_SIZE, @@ -443,7 +495,7 @@ errlHndl_t PreVerifiedLidMgr::loadImage(const uint64_t i_imgAddr, // out. if(cv_addFakeHdrs) { - TRACDCOMP(g_trac_runtime, "PreVerifiedLidMgr::loadImage fake header load"); + TRACFCOMP(g_trac_runtime, "PreVerifiedLidMgr::loadImage inject fake header before image without one"); SECUREBOOT::ContainerHeader l_fakeHdr; l_errl = l_fakeHdr.setFakeHeader(i_imgSize, PNOR::SectionIdToString(cv_curPnorSecId)); @@ -455,9 +507,34 @@ errlHndl_t PreVerifiedLidMgr::loadImage(const uint64_t i_imgAddr, memcpy(reinterpret_cast(l_tmpVaddr), l_fakeHdr.fakeHeader(), PAGE_SIZE); + + if(i_imgSize <= PAGE_SIZE) + { + TRACFCOMP( g_trac_runtime, ERR_MRK "PreVerifiedLidMgr::loadImage - Image size 0x%X is not greater than the header size 0x%X, thus no space to inject fake header", + i_imgSize, PAGE_SIZE); + + /*@ + * @errortype + * @severity ERRL_SEV_UNRECOVERABLE + * @moduleid RUNTIME::MOD_PREVERLIDMGR_LOAD_IMAGE + * @reasoncode RUNTIME::RC_PREVER_INVALID_SIZE + * @userdata1 Size of section including space for header + * @userdata2 Size of header + * @devdesc No space left for fake header injection + * @custdesc Platform security problem detected + */ + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + RUNTIME::MOD_PREVERLIDMGR_LOAD_IMAGE, + RUNTIME::RC_PREVER_INVALID_SIZE, + i_imgSize, + PAGE_SIZE, + true); + l_errl->collectTrace(RUNTIME_COMP_NAME); + break; + } // Include rest of image after header // NOTE: Do not use aligned size for memcpy - assert(i_imgSize > PAGE_SIZE, "PreVerifiedLidMgr::loadImage - caller did not include size of header for total size"); memcpy(reinterpret_cast(l_tmpVaddr+PAGE_SIZE), reinterpret_cast(i_imgAddr), i_imgSize-PAGE_SIZE); diff --git a/src/usr/secureboot/base/header.C b/src/usr/secureboot/base/header.C index 77d756934..58f08c632 100644 --- a/src/usr/secureboot/base/header.C +++ b/src/usr/secureboot/base/header.C @@ -28,6 +28,9 @@ #include #include #include +#include "../common/securetrace.H" +#include "../common/errlud_secure.H" +#include namespace SECUREBOOT { @@ -36,15 +39,44 @@ namespace SECUREBOOT return Singleton
::instance(); } - void Header::loadHeader() + errlHndl_t Header::loadHeader() { + errlHndl_t l_errl = nullptr; + + do { + const void* const pHeader = g_BlToHbDataManager.getHbbHeader(); // Fatal code bug if called with nullptr pointer - assert(pHeader != nullptr, - "BUG! In Header::loadHeader(), expected valid address for base " - "image header, but got nullptr."); + if (pHeader == nullptr) + { + SB_ERR("Header::loadHeader(), expected valid address for base image header, but got nullptr."); + /*@ + * @errortype + * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid SECUREBOOT::MOD_SECURE_LOAD_HEADER + * @reasoncode SECUREBOOT::RC_INVALID_BASE_HEADER + * @userdata1 0 + * @userdata2 0 + * @devdesc Hostboot Base Image Header not valid + * @custdesc Firmware Error + */ + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + SECUREBOOT::MOD_SECURE_LOAD_HEADER, + SECUREBOOT::RC_INVALID_BASE_HEADER, + 0, + 0, + true); + addSecureUserDetailsToErrlog(l_errl); + l_errl->collectTrace(SECURE_COMP_NAME); + break; + } + _set(pHeader); + } while(0); + + return l_errl; } void Header::_set( diff --git a/src/usr/secureboot/base/service.C b/src/usr/secureboot/base/service.C index 21900a5fa..1f5b5d83d 100644 --- a/src/usr/secureboot/base/service.C +++ b/src/usr/secureboot/base/service.C @@ -234,8 +234,6 @@ errlHndl_t getAllSecurityRegisters(std::vector & o_regs, DEVICE_FSI_ADDRESS(op_addr) ); } - assert(op_actual_size == op_expected_size,"getAllSecurityRegisters: BUG! size returned from device write (%d) is not the expected size of %d", op_actual_size, op_expected_size); - if( err ) { // Something failed on the read. Commit the error @@ -249,6 +247,33 @@ errlHndl_t getAllSecurityRegisters(std::vector & o_regs, errlCommit( err, SECURE_COMP_ID ); continue; } + + if (op_actual_size != op_expected_size) + { + SB_ERR("getAllSecurityRegisters: size returned from device write (%d) is not the expected size of %d", + op_actual_size, op_expected_size); + /*@ + * @errortype + * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid SECUREBOOT::MOD_SECURE_GET_ALL_SEC_REGS + * @reasoncode SECUREBOOT::RC_DEVICE_WRITE_ERR + * @userdata1 Actual size written + * @userdata2 Expected size written + * @devdesc Device write did not return expected size + * @custdesc Firmware Error + */ + err = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + SECUREBOOT::MOD_SECURE_GET_ALL_SEC_REGS, + SECUREBOOT::RC_DEVICE_WRITE_ERR, + op_actual_size, + op_expected_size, + true); + addSecureUserDetailsToErrlog(err); + err->collectTrace(SECURE_COMP_NAME); + break; + } + // push back result l_secRegValues.tgt=procTgt; l_secRegValues.addr=op_addr; @@ -316,7 +341,11 @@ void* initializeBase(void* unused) #endif // Load original header. - Singleton
::instance().loadHeader(); + l_errl = Singleton
::instance().loadHeader(); + if (l_errl) + { + break; + } } while(0); return l_errl; @@ -613,11 +642,43 @@ uint8_t getSbeSecurityMode() return g_sbeSecurityMode; } -void setSbeSecurityMode(uint8_t i_sbeSecurityMode) +errlHndl_t setSbeSecurityMode(uint8_t i_sbeSecurityMode) { - assert(i_sbeSecurityMode == 0 || i_sbeSecurityMode == 1, - "SBE Security Mode can only be set to 0 or 1"); + errlHndl_t l_errl = nullptr; + + do { + // Ensure a valid mode + if (i_sbeSecurityMode != 0 && i_sbeSecurityMode != 1) + { + SB_ERR("SBE Security Mode can only be set to 0 or 1"); + + /*@ + * @errortype + * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid SECUREBOOT::MOD_SECURE_SET_SBE_SECURE_MODE + * @reasoncode SECUREBOOT::RC_SBE_INVALID_SEC_MODE + * @userdata1 Security mode to set + * @userdata2 0 + * @devdesc Invalid SBE security mode + * @custdesc Platform security problem detected + */ + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + SECUREBOOT::MOD_SECURE_SET_SBE_SECURE_MODE, + SECUREBOOT::RC_SBE_INVALID_SEC_MODE, + i_sbeSecurityMode, + 0, + true); + l_errl->collectTrace(SECURE_COMP_NAME); + addSecureUserDetailsToErrlog(l_errl); + break; + } + g_sbeSecurityMode = i_sbeSecurityMode; + + } while(0); + + return l_errl; } } //namespace SECUREBOOT diff --git a/src/usr/secureboot/base/settings.C b/src/usr/secureboot/base/settings.C index eb25aea11..4ebb77dd1 100644 --- a/src/usr/secureboot/base/settings.C +++ b/src/usr/secureboot/base/settings.C @@ -284,9 +284,31 @@ namespace SECUREBOOT break; } - assert(actSize == expSize, - "writeSecurityRegister: BUG! size returned from device write (%d) " - "is not the expected size of %d",actSize,expSize); + if(actSize != expSize) + { + SB_ERR("writeSecurityRegister: size returned from device write (%d) is not the expected size of %d", + actSize, expSize); + /*@ + * @errortype + * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid SECUREBOOT::MOD_SECURE_WRITE_REG + * @reasoncode SECUREBOOT::RC_DEVICE_WRITE_ERR + * @userdata1 Actual size written + * @userdata2 Expected size written + * @devdesc Device write did not return expected size + * @custdesc Firmware Error + */ + pError = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + SECUREBOOT::MOD_SECURE_WRITE_REG, + SECUREBOOT::RC_DEVICE_WRITE_ERR, + actSize, + expSize, + true); + pError->collectTrace(SECURE_COMP_NAME); + addSecureUserDetailsToErrlog(pError); + break; + } } while(0); @@ -341,10 +363,30 @@ namespace SECUREBOOT } // Make sure the processor is SCOMable - if (i_pProc != MASTER_PROCESSOR_CHIP_TARGET_SENTINEL) + if (i_pProc != MASTER_PROCESSOR_CHIP_TARGET_SENTINEL && + !i_pProc->getAttr().useXscom) { - assert(i_pProc->getAttr().useXscom, - "Bug! Processor security register read too early."); + SB_ERR("readSecurityRegister: Processor security register read too early"); + /*@ + * @errortype + * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid SECUREBOOT::MOD_SECURE_READ_REG + * @reasoncode SECUREBOOT::RC_PROC_NOT_SCOMABLE + * @userdata1 Use XSCOM bool + * @userdata2 Target's HUID + * @devdesc Processor security register read too early + * @custdesc Firmware Error + */ + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + SECUREBOOT::MOD_SECURE_READ_REG, + SECUREBOOT::RC_PROC_NOT_SCOMABLE, + i_pProc->getAttr().useXscom, + TO_UINT64(get_huid(i_pProc)), + true); + l_errl->collectTrace(SECURE_COMP_NAME); + addSecureUserDetailsToErrlog(l_errl); + break; } // Read security switch setting from processor. @@ -356,9 +398,32 @@ namespace SECUREBOOT { break; } - assert(size == sizeof(o_regValue), - "size returned from device read is not the expected size of %i", - sizeof(o_regValue)); + + if (size != sizeof(o_regValue)) + { + SB_ERR("readSecurityRegister: size returned from device read (%d) is not the expected size of %d", + size, sizeof(o_regValue)); + /*@ + * @errortype + * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid SECUREBOOT::MOD_SECURE_READ_REG + * @reasoncode SECUREBOOT::RC_DEVICE_READ_ERR + * @userdata1 Actual size read + * @userdata2 Expected size read + * @devdesc Processor security register read too early + * @custdesc Firmware Error + */ + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + SECUREBOOT::MOD_SECURE_READ_REG, + SECUREBOOT::RC_DEVICE_READ_ERR, + size, + sizeof(o_regValue), + true); + l_errl->collectTrace(SECURE_COMP_NAME); + addSecureUserDetailsToErrlog(l_errl); + break; + } } while(0); diff --git a/src/usr/util/runtime/utillidmgr_rt.C b/src/usr/util/runtime/utillidmgr_rt.C index 05f15c3c4..e5d381a2c 100644 --- a/src/usr/util/runtime/utillidmgr_rt.C +++ b/src/usr/util/runtime/utillidmgr_rt.C @@ -41,8 +41,17 @@ UtilLidMgr::UtilLidMgr(uint32_t i_lidId) : iv_isLidInPnor(false), iv_lidBuffer(nullptr), iv_lidSize(0), iv_isLidInVFS(false), iv_isLidInHbResvMem(false) { + errlHndl_t l_err = nullptr; iv_spBaseServicesEnabled = INITSERVICE::spBaseServicesEnabled(); - updateLid(i_lidId); + l_err = updateLid(i_lidId); + if (l_err) + { + UTIL_FT(ERR_MRK"UtilLidMgr::UtilLidMgr() cstor failed to update Lid (0x%X)", + i_lidId); + errlCommit(l_err,UTIL_COMP_ID); + // Set to invalid lid id and allow to continue + iv_lidId = Util::INVALID_LIDID; + } } UtilLidMgr::~UtilLidMgr() @@ -61,10 +70,20 @@ errlHndl_t UtilLidMgr::setLidId(uint32_t i_lidId) { errlHndl_t l_err = nullptr; + do { //must call cleanup before updateLid l_err = cleanup(); + if (l_err) + { + break; + } - updateLid(i_lidId); + l_err = updateLid(i_lidId); + if (l_err) + { + break; + } + } while(0); return l_err; } @@ -280,17 +299,19 @@ errlHndl_t UtilLidMgr::cleanup() return l_err; } -void UtilLidMgr::updateLid(uint32_t i_lidId) +errlHndl_t UtilLidMgr::updateLid(uint32_t i_lidId) { UTIL_FT("UtilLidMgr::updateLid - i_lidId=0x%.8X", i_lidId); iv_lidId = i_lidId; + errlHndl_t l_err = nullptr; + + do { // First check if lid is already in hostboot reserved memory // In securemode the lid is pre-verified if (TARGETING::is_sapphire_load() && lidInHbResvMem(iv_lidId)) { UTIL_FT("UtilLidMgr::updateLid - lid in Hb Resv Mem"); - getLidPnorSectionInfo(iv_lidId, iv_lidPnorInfo); iv_isLidInHbResvMem = true; } // Check if PNOR is access is supported @@ -304,10 +325,18 @@ void UtilLidMgr::updateLid(uint32_t i_lidId) UTIL_FT("UtilLidMgr::updateLid - lid in PNOR"); // If it's in PNOR it's not technically a lid // so use a slightly different extension - iv_isLidInPnor = getLidPnorSectionInfo(iv_lidId, iv_lidPnorInfo); + l_err = getLidPnorSectionInfo(iv_lidId, iv_lidPnorInfo, iv_isLidInPnor); + if (l_err) + { + break; + } } sprintf(iv_lidFileName, "%x.lidbin", iv_lidId); iv_isLidInVFS = VFS::module_exists(iv_lidFileName); + + } while (0); + + return l_err; } const uint32_t * UtilLidMgr::getLidList(size_t * o_num) diff --git a/src/usr/util/utillidmgr.C b/src/usr/util/utillidmgr.C index d69d02d0b..5f329b2d4 100644 --- a/src/usr/util/utillidmgr.C +++ b/src/usr/util/utillidmgr.C @@ -56,19 +56,48 @@ UtilLidMgr::UtilLidMgr(uint32_t i_lidId) ,iv_lidImageSize(0) ,iv_lidSize(0) { + errlHndl_t l_err = nullptr; iv_spBaseServicesEnabled = INITSERVICE::spBaseServicesEnabled(); - updateLid(i_lidId); + l_err = updateLid(i_lidId); + if (l_err) + { + uint64_t l_reasonCode = l_err->reasonCode(); + UTIL_FT(ERR_MRK"UtilLidMgr::UtilLidMgr() Failed to update Lid (0x%X) shutting down rc=0x%08X", + i_lidId, l_reasonCode); + errlCommit(l_err,UTIL_COMP_ID); + INITSERVICE::doShutdown(l_reasonCode); + } + + // On non-FSP based systems only get LIDs from either PNOR or VFS + if ( (iv_spBaseServicesEnabled == false) && + (iv_isLidInPnor == false) && + (iv_isLidInVFS == false) + ) + { + UTIL_FT(ERR_MRK"UtilLidMgr::UtilLidMgr() Requested lid 0x%X not in PNOR or VFS which is required on non-FSP based systems", + i_lidId); + + /*@ + * @errortype + * @moduleid Util::UTIL_LIDMGR_CSTOR + * @reasoncode Util::UTIL_LIDMGR_INVAL_LID_REQUEST + * @userdata1 LID ID + * @userdata2 0 + * @devdesc Lid not in PNOR or VFS for non-FSP systems + * @custdesc Firmware encountered an internal error. + */ + l_err = new ErrlEntry( + ERRL_SEV_UNRECOVERABLE, + Util::UTIL_LIDMGR_CSTOR, + Util::UTIL_LIDMGR_INVAL_LID_REQUEST, + i_lidId, + 0, + true /*Add HB Software Callout*/); + l_err->collectTrace(UTIL_COMP_NAME); + errlCommit(l_err,UTIL_COMP_ID); + INITSERVICE::doShutdown(Util::UTIL_LIDMGR_INVAL_LID_REQUEST); + } -#ifdef CONFIG_SECUREBOOT - // In SECUREBOOT mode ensure that OpenPower systems only get LIDs from - // either PNOR or VFS where we can trust the security - assert( !(( iv_spBaseServicesEnabled == false ) && - ( iv_isLidInPnor == false ) && - ( iv_isLidInVFS == false ) - ), "UtilLidMgr::UtilLidMgr: Secureboot: OpenPower requesting LID " - "that is not in PNOR or VFS" - ); -#endif } /////////////////////////////////////////////////////////// @@ -892,28 +921,47 @@ errlHndl_t UtilLidMgr::setLidId(uint32_t i_lidId) { errlHndl_t l_err = nullptr; + do { //must call cleanup before updateLid l_err = cleanup(); + if (l_err) + { + break; + } - updateLid(i_lidId); + l_err = updateLid(i_lidId); + if (l_err) + { + break; + } + } while(0); return l_err; } /////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////// -void UtilLidMgr::updateLid(uint32_t i_lidId) +errlHndl_t UtilLidMgr::updateLid(uint32_t i_lidId) { iv_lidId = i_lidId; + errlHndl_t l_err = nullptr; + + do { //if it's in PNOR, it's not technically lid, so use a slightly //different extension. sprintf(iv_lidFileName, "%x.lidbin", iv_lidId); - iv_isLidInPnor = getLidPnorSectionInfo(iv_lidId, iv_lidPnorInfo); + l_err = getLidPnorSectionInfo(iv_lidId, iv_lidPnorInfo, iv_isLidInPnor); + if (l_err) + { + UTIL_FT("UtilLidMgr::updateLid - getLidPnorSectionInfo failed"); + break; + } UTIL_DT(INFO_MRK "UtilLidMgr: LID 0x%.8X in pnor: %d", iv_lidId ,iv_isLidInPnor); iv_isLidInVFS = VFS::module_exists(iv_lidFileName); + } while(0); - return; + return l_err; } diff --git a/src/usr/util/utillidpnor.C b/src/usr/util/utillidpnor.C index 25c90c73e..c7118c915 100644 --- a/src/usr/util/utillidpnor.C +++ b/src/usr/util/utillidpnor.C @@ -97,11 +97,12 @@ PNOR::SectionId getLidPnorSection(const LidId i_lid) } // end Util namespace -bool UtilLidMgr::getLidPnorSectionInfo(uint32_t i_lidId, - PNOR::SectionInfo_t &o_lidPnorInfo) +errlHndl_t UtilLidMgr::getLidPnorSectionInfo(const uint32_t i_lidId, + PNOR::SectionInfo_t &o_lidPnorInfo, + bool &o_isLidInPnor) { errlHndl_t l_err = nullptr; - bool l_lidInPnor = false; + o_isLidInPnor = false; // Search if a lid id maps to pnor section auto l_secId = Util::getLidPnorSection(static_cast(i_lidId)); @@ -141,20 +142,19 @@ bool UtilLidMgr::getLidPnorSectionInfo(uint32_t i_lidId, o_lidPnorInfo.id = PNOR::INVALID_SECTION; delete l_err; l_err = nullptr; - UTIL_FT("UtilLidMgr::getLidPnorSectionInfo Lid 0x%X ignore getSectionInfo error", + UTIL_FT("UtilLidMgr::getLidPnorSectionInfo Lid 0x%X ignore getSectionInfo INVALID_SECTION error", i_lidId); break; } else if (l_err) { - UTIL_FT(ERR_MRK"UtilLidMgr::getLidPnorSectionInfo Lid 0x%X getSectionInfo error shutting down rc=0x%08X", + UTIL_FT(ERR_MRK"UtilLidMgr::getLidPnorSectionInfo Lid 0x%X getSectionInfo failed rc=0x%08X", l_err->reasonCode()); - errlCommit(l_err, UTIL_COMP_ID); break; } else { - l_lidInPnor = true; + o_isLidInPnor = true; UTIL_FT("UtilLidMgr::getLidPnorSectionInfo Lid 0x%X in PNOR", i_lidId); #ifdef CONFIG_SECUREBOOT #ifndef __HOSTBOOT_RUNTIME @@ -165,14 +165,11 @@ bool UtilLidMgr::getLidPnorSectionInfo(uint32_t i_lidId, // Load the secure section l_err = loadSecureSection(l_secId); - - // If secure section fails to load log the error and assert if (l_err) { - errlCommit(l_err, UTIL_COMP_ID); - assert(false,"UtilLidMgr::getLidPnorSectionInfo: attempt to " - "load Secure Section %d failed", - l_secId); + UTIL_FT("UtilLidMgr::getLidPnorSectionInfo loadSecureSection failed for Section %d", + l_secId); + break; } // In Secureboot, rather than using the whole partition size, @@ -189,5 +186,5 @@ bool UtilLidMgr::getLidPnorSectionInfo(uint32_t i_lidId, } } while(0); - return l_lidInPnor; + return l_err; } -- cgit v1.2.1