summaryrefslogtreecommitdiffstats
path: root/src/usr/runtime
diff options
context:
space:
mode:
authorStephen Cprek <smcprek@us.ibm.com>2017-10-31 13:01:30 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2017-11-19 15:54:51 -0500
commit81279c1d146d8ee920494c7817cdd72f165dd373 (patch)
treed616d0914823c8c25592e8276e0610ba1c9d2a28 /src/usr/runtime
parent63a026113332464fc3bcc73369ba35bfe8f62b6f (diff)
downloadtalos-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/runtime')
-rw-r--r--src/usr/runtime/common/runtime_utils.C18
-rw-r--r--src/usr/runtime/populate_hbruntime.C16
-rw-r--r--src/usr/runtime/preverifiedlidmgr.C66
-rw-r--r--src/usr/runtime/test/testpreverifiedlidmgr.H13
4 files changed, 96 insertions, 17 deletions
diff --git a/src/usr/runtime/common/runtime_utils.C b/src/usr/runtime/common/runtime_utils.C
index 04a42f502..7b900389f 100644
--- a/src/usr/runtime/common/runtime_utils.C
+++ b/src/usr/runtime/common/runtime_utils.C
@@ -58,4 +58,22 @@ bool isPreVerifiedSection(const PNOR::SectionId i_section)
return l_result;
}
+bool isPreVerifiedSectionSecure(const PNOR::SectionId i_section)
+{
+ bool l_result = false;
+ auto it = find_if(preVerifiedPnorSections.begin(),
+ preVerifiedPnorSections.end(),
+ [&i_section](const PreVerifyPair& p)
+ {
+ return p.first == i_section;
+ });
+
+ if (it != preVerifiedPnorSections.end())
+ {
+ l_result = it->second;
+ }
+
+ return l_result;
+}
+
} \ No newline at end of file
diff --git a/src/usr/runtime/populate_hbruntime.C b/src/usr/runtime/populate_hbruntime.C
index 199b55ecb..eb7a5a7b5 100644
--- a/src/usr/runtime/populate_hbruntime.C
+++ b/src/usr/runtime/populate_hbruntime.C
@@ -76,7 +76,6 @@
#include <pnor/pnor_reasoncodes.H>
#include <runtime/common/runtime_utils.H>
-
namespace RUNTIME
{
@@ -557,7 +556,8 @@ errlHndl_t fill_RsvMem_hbData(uint64_t & io_start_address,
return l_elog;
}
-errlHndl_t hbResvLoadSecureSection (const PNOR::SectionId i_sec)
+errlHndl_t hbResvLoadSecureSection (const PNOR::SectionId i_sec,
+ bool i_verified)
{
TRACFCOMP( g_trac_runtime,ENTER_MRK"hbResvloadSecureSection() sec %s",
PNOR::SectionIdToString(i_sec));
@@ -603,16 +603,18 @@ errlHndl_t hbResvLoadSecureSection (const PNOR::SectionId i_sec)
auto l_pnorVaddr = l_info.vaddr;
auto l_imgSize = l_info.size;
- // If section is signed, only the protected size was loaded into memory
-#ifdef CONFIG_SECUREBOOT
- if (l_info.secure)
+ // If section is signed, only the protected size was loaded into memory
+ if (i_verified)
{
+#ifdef CONFIG_SECUREBOOT
l_imgSize = l_info.secureProtectedPayloadSize;
// Include secure header
l_pnorVaddr -= PAGESIZE;
+#endif
+ // Add size for secure header.
+ // NOTE: if SB compiled out, a header will be injected later
l_imgSize += PAGESIZE;
}
-#endif
// Load Pnor section into HB reserved memory
l_elog = PreVerifiedLidMgr::loadFromPnor(i_sec, l_pnorVaddr, l_imgSize);
@@ -1070,7 +1072,7 @@ errlHndl_t populate_HbRsvMem(uint64_t i_nodeId)
// Handle all Pre verified PNOR sections
for (const auto & secIdPair : preVerifiedPnorSections)
{
- l_elog = hbResvLoadSecureSection(secIdPair.first);
+ l_elog = hbResvLoadSecureSection(secIdPair.first, secIdPair.second);
if (l_elog)
{
break;
diff --git a/src/usr/runtime/preverifiedlidmgr.C b/src/usr/runtime/preverifiedlidmgr.C
index 16cf15c10..62671860f 100644
--- a/src/usr/runtime/preverifiedlidmgr.C
+++ b/src/usr/runtime/preverifiedlidmgr.C
@@ -36,6 +36,8 @@
#include <arch/ppc.H>
#include <targeting/common/target.H>
#include <targeting/common/attributes.H>
+#include <secureboot/containerheader.H>
+#include <runtime/common/runtime_utils.H>
extern trace_desc_t *g_trac_runtime;
@@ -47,6 +49,8 @@ PreVerifiedLidMgr::ResvMemInfo PreVerifiedLidMgr::cv_resvMemInfo {};
PreVerifiedLidMgr::ResvMemInfo PreVerifiedLidMgr::cv_phypResvMemInfo {};
mutex_t PreVerifiedLidMgr::cv_mutex = MUTEX_INITIALIZER;
mutex_t PreVerifiedLidMgr::cv_loadImageMutex = MUTEX_INITIALIZER;
+bool PreVerifiedLidMgr::cv_addFakeHdrs = false;
+PNOR::SectionId PreVerifiedLidMgr::cv_curPnorSecId = PNOR::INVALID_SECTION;
/********************
Public Methods
@@ -156,6 +160,27 @@ errlHndl_t PreVerifiedLidMgr::_loadFromPnor(const PNOR::SectionId i_sec,
TRACFCOMP(g_trac_runtime, ENTER_MRK"PreVerifiedLidMgr::_loadFromPnor - sec %s",
PNOR::SectionIdToString(i_sec));
+#ifdef CONFIG_SECUREBOOT
+ // If SB compiled in, only add fake secure header if the section is never
+ // signed. e.g. RINGOVD section
+ // Otherwise always add fake secure header when SB compiled out
+ if (!RUNTIME::isPreVerifiedSectionSecure(i_sec))
+ {
+#endif
+ // Check if Header is mising
+ if (!PNOR::cmpSecurebootMagicNumber(
+ reinterpret_cast<uint8_t*>(i_addr)))
+ {
+ TRACFCOMP(g_trac_runtime, "PreVerifiedLidMgr::_loadFromPnor adding fake header to %s",
+ PNOR::SectionIdToString(i_sec));
+ // Add fake headers to pnor loads
+ cv_addFakeHdrs = true;
+ cv_curPnorSecId = i_sec;
+ }
+#ifdef CONFIG_SECUREBOOT
+ }
+#endif
+
errlHndl_t l_errl = nullptr;
do {
@@ -206,10 +231,11 @@ errlHndl_t PreVerifiedLidMgr::_loadFromPnor(const PNOR::SectionId i_sec,
{
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,
- i_size,
+ i_size-PAGE_SIZE,
l_lidStr);
if(l_errl)
{
@@ -253,6 +279,10 @@ errlHndl_t PreVerifiedLidMgr::_loadFromPnor(const PNOR::SectionId i_sec,
} while(0);
+ // Force fake header bool to be false and clear cur PNOR section id
+ cv_addFakeHdrs = false;
+ cv_curPnorSecId = PNOR::INVALID_SECTION;
+
TRACFCOMP( g_trac_runtime, EXIT_MRK"PreVerifiedLidMgr::_loadFromPnor");
mutex_unlock(&cv_loadImageMutex);
@@ -271,6 +301,9 @@ errlHndl_t PreVerifiedLidMgr::_loadFromMCL(const uint32_t i_lidId,
TRACFCOMP(g_trac_runtime, ENTER_MRK"PreVerifiedLidMgr::_loadFromMCL lid = 0x%X",
i_lidId);
+ // Force fake header bool to be false in MCL path
+ cv_addFakeHdrs = false;
+
errlHndl_t l_errl = nullptr;
// Switch to Different Memory Info for PHYP component
@@ -396,11 +429,32 @@ errlHndl_t PreVerifiedLidMgr::loadImage(const uint64_t i_imgAddr,
TRACDCOMP(g_trac_runtime, "PreVerifiedLidMgr::loadImage - curAddr 0x%X, size 0x%X, vaddr 0x%X",
cv_pResvMemInfo->curAddr, i_imgSize, l_tmpVaddr);
- // Include Header page from pnor image.
- // NOTE: Do not use aligned size for memcpy
- memcpy(reinterpret_cast<void*>(l_tmpVaddr),
- reinterpret_cast<void*>(i_imgAddr),
- i_imgSize);
+ // Inject a fake header when loading from PNOR and secureboot is compiled
+ // out.
+ if(cv_addFakeHdrs)
+ {
+ TRACDCOMP(g_trac_runtime, "PreVerifiedLidMgr::loadImage fake header load");
+ SECUREBOOT::ContainerHeader l_fakeHdr(i_imgSize,
+ SectionIdToString(cv_curPnorSecId));
+ // Inject Fake header into reserved memory
+ memcpy(reinterpret_cast<void*>(l_tmpVaddr),
+ l_fakeHdr.fakeHeader(),
+ PAGE_SIZE);
+ // 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<void*>(l_tmpVaddr+PAGE_SIZE),
+ reinterpret_cast<void*>(i_imgAddr),
+ i_imgSize-PAGE_SIZE);
+ }
+ else
+ {
+ TRACDCOMP(g_trac_runtime, "PreVerifiedLidMgr::loadImage default load");
+ // NOTE: Do not use aligned size for memcpy
+ memcpy(reinterpret_cast<void*>(l_tmpVaddr),
+ reinterpret_cast<void*>(i_imgAddr),
+ i_imgSize);
+ }
l_errl = RUNTIME::unmapVirtAddr(l_tmpVaddr);
if(l_errl)
diff --git a/src/usr/runtime/test/testpreverifiedlidmgr.H b/src/usr/runtime/test/testpreverifiedlidmgr.H
index 3863ed27e..26879574e 100644
--- a/src/usr/runtime/test/testpreverifiedlidmgr.H
+++ b/src/usr/runtime/test/testpreverifiedlidmgr.H
@@ -83,7 +83,8 @@ class PreVerifiedLidMgrTest : public CxxTest::TestSuite
// Handle all Pre verified PNOR sections
for (const auto & secIdPair : RUNTIME::preVerifiedPnorSections)
{
- l_errl = RUNTIME::hbResvLoadSecureSection(secIdPair.first);
+ l_errl = RUNTIME::hbResvLoadSecureSection(secIdPair.first,
+ secIdPair.second);
if (l_errl)
{
errlCommit(l_errl, RUNTIME_COMP_ID);
@@ -100,16 +101,20 @@ class PreVerifiedLidMgrTest : public CxxTest::TestSuite
// Each section has 2 lids each (Header, Content) except the RINGOVD
// section. It only has 1 or is inhibited in secure mode
size_t l_numSections = RUNTIME::preVerifiedPnorSections.size();
- size_t l_expectedLids = (2 * l_numSections) - 1;
+ // See utillidpnor.C for more info on num of lids
+ size_t l_expectedLids = (2 * l_numSections);
if (SECUREBOOT::enabled())
{
- l_expectedLids--;
+ // RINGOVD not permitted in secure mode
+ l_expectedLids -= 2;
}
// Ensure the expected number of lids were loaded.
if (l_preVerLidMgr.cv_lidsLoaded.size() != l_expectedLids)
{
- TS_FAIL("testLoadFromPnor> Num of lids loaded not correct");
+ TS_FAIL("testLoadFromPnor> Num of lids loaded not correct %d expected %d",
+ l_preVerLidMgr.cv_lidsLoaded.size(),
+ l_expectedLids);
break;
}
OpenPOWER on IntegriCloud