summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlya Smirnov <ismirno@us.ibm.com>2018-04-02 16:39:21 -0500
committerNicholas E. Bofferding <bofferdn@us.ibm.com>2018-04-12 16:20:04 -0400
commitf5cd23d6c3be17356e0851ec5d5bb65cee48f15f (patch)
treeecdfb7de737d9b97649f4cd025b392d256b1e470
parente84f5604125d704d098efbea74f8368060be593d (diff)
downloadtalos-hostboot-f5cd23d6c3be17356e0851ec5d5bb65cee48f15f.tar.gz
talos-hostboot-f5cd23d6c3be17356e0851ec5d5bb65cee48f15f.zip
Mark Read-Only Partitions as Such
Partitions marked with readOnly tag in the xml were treated as WRITABLE in the code. This change modifies the permissions to be READ_ONLY and adds unit tests to test the read only functionality. Change-Id: I8c1f23fd7e30edc38ff882c59716ab63a4f310e6 CQ: SW423350 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/56771 CI-Ready: ILYA SMIRNOV <ismirno@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@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: Nicholas E. Bofferding <bofferdn@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/57066 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
-rw-r--r--src/include/usr/pnor/pnor_reasoncodes.H1
-rw-r--r--src/usr/pnor/pnorrp.C15
-rw-r--r--src/usr/pnor/test/pnorrptest.H188
-rw-r--r--src/usr/secureboot/base/test/securerommgrtest.H20
4 files changed, 153 insertions, 71 deletions
diff --git a/src/include/usr/pnor/pnor_reasoncodes.H b/src/include/usr/pnor/pnor_reasoncodes.H
index 4dd2ef1c4..2835f8a15 100644
--- a/src/include/usr/pnor/pnor_reasoncodes.H
+++ b/src/include/usr/pnor/pnor_reasoncodes.H
@@ -187,6 +187,7 @@ namespace PNOR
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,
+ RC_READ_ONLY_PERM_FAIL = PNOR_COMP_ID | 0x3D,
//@fixme-RTC:131607-Temporary value to allow HWSV compile
//termination_rc
diff --git a/src/usr/pnor/pnorrp.C b/src/usr/pnor/pnorrp.C
index e33a1b0c3..df88ba821 100644
--- a/src/usr/pnor/pnorrp.C
+++ b/src/usr/pnor/pnorrp.C
@@ -1776,32 +1776,31 @@ errlHndl_t PnorRP::setVirtAddrs(void)
// Handle section permissions
if (iv_TOC[i].misc & FFS_MISC_READ_ONLY)
{
- // Need to set permissions to allow writing to virtual
- // addresses, but prevents the kernel from ejecting
- // dirty pages (no WRITE_TRACKED).
+ // Partitions marked with readOnly flag should be
+ // READ_ONLY and not WRITABLE.
int rc = mm_set_permission(
(void*)iv_TOC[i].virtAddr,
iv_TOC[i].size,
- WRITABLE);
+ READ_ONLY);
if (rc)
{
- TRACFCOMP(g_trac_pnor, "E>PnorRP::readTOC: Failed to set block permissions to WRITABLE for section %s.",
+ TRACFCOMP(g_trac_pnor, "E>PnorRP::readTOC: Failed to set block permissions to READ_ONLY for section %s.",
SectionIdToString(i));
/*@
* @errortype
* @moduleid PNOR::MOD_PNORRP_READTOC
- * @reasoncode PNOR::RC_WRITABLE_PERM_FAIL
+ * @reasoncode PNOR::RC_READ_ONLY_PERM_FAIL
* @userdata1 PNOR section id
* @userdata2 PNOR section vaddr
* @devdesc Could not set permissions of the
- * given PNOR section to WRITABLE
+ * given PNOR section to READ_ONLY
* @custdesc A problem occurred while reading
* Processor NOR flash partition table
*/
l_errhdl = new ERRORLOG::ErrlEntry(
ERRORLOG::ERRL_SEV_UNRECOVERABLE,
PNOR::MOD_PNORRP_READTOC,
- PNOR::RC_WRITABLE_PERM_FAIL,
+ PNOR::RC_READ_ONLY_PERM_FAIL,
i,
iv_TOC[i].virtAddr,
true /*Add HB SW Callout*/);
diff --git a/src/usr/pnor/test/pnorrptest.H b/src/usr/pnor/test/pnorrptest.H
index 942eff9ab..5108840f5 100644
--- a/src/usr/pnor/test/pnorrptest.H
+++ b/src/usr/pnor/test/pnorrptest.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2017 */
+/* Contributors Listed Below - COPYRIGHT 2011,2018 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -39,6 +39,7 @@
#include <sys/msg.h>
#include <limits.h>
#include <sys/mm.h>
+#include <sys/task.h>
#include <targeting/common/targetservice.H>
#include <devicefw/userif.H>
#include <config.h>
@@ -625,82 +626,53 @@ class PnorRpTest : public CxxTest::TestSuite
}
/**
- * @brief PNOR RP test - ReadOnlyTag
- * Tests if readOnly tag on a section is being processed correctly
+ * @brief PNOR RP test - read_ReadOnly_partition
+ * Tests if we can read a readOnly partition
*
*/
- void test_ReadOnlyTag(void)
+ void test_read_ReadOnly_partition(void)
{
- TRACFCOMP(g_trac_pnor, "PnorRpTest::test_ReadOnlyTag Start" );
- PNOR::SectionInfo_t l_info;
- errlHndl_t l_errhdl = NULL;
- uint64_t chip_select = 0xF;
- bool needs_ecc = false;
+ TRACFCOMP(g_trac_pnor,"PnorRpTest::test_read_ReadOnly_partition Start");
+
+ int l_status = TASK_STATUS_EXITED_CLEAN;
+ PNOR::SectionId l_testroSecId = PNOR::TESTRO;
+ tid_t l_childTask =
+ task_create(readFromReadOnlyPartition, &l_testroSecId);
- l_errhdl = PNOR::getSectionInfo(PNOR::TESTRO, l_info);
- if( l_errhdl )
+ if((l_childTask != task_wait_tid(l_childTask, &l_status, nullptr)) ||
+ (l_status != TASK_STATUS_EXITED_CLEAN))
{
- TRACFCOMP(g_trac_pnor, "PnorRpTest::test_ReadOnlyTag> ERROR : getSectionInfo returned error for %d : RC=%X",
- PNOR::TESTRO, l_errhdl->reasonCode());
- ERRORLOG::errlCommit(l_errhdl, PNOR_COMP_ID);
- TS_FAIL( "PnorRpTest::test_ReadOnlyTag> ERROR : could not read pnor section %d", PNOR::TESTRO);
+ TS_FAIL("Could not read from readOnly partition.");
}
+ TRACFCOMP(g_trac_pnor,"PnorRpTest::test_read_ReadOnly_partition End");
+ }
- // Write some data
- const uint64_t l_writeData = 0x1122334455667788;
- uint64_t* l_dataptr = reinterpret_cast<uint64_t*> (l_info.vaddr);
- l_dataptr[0] = l_writeData;
+ /**
+ * @brief PNOR RP test - write_ReadOnly_partition
+ * Tests if we can write to a readOnly partition (fail expected)
+ *
+ */
+ void test_write_ReadOnly_partition(void)
+ {
+ TRACFCOMP(g_trac_pnor,
+ "PnorRpTest::test_write_ReadOnly_partition Start");
- // Flush the page to make sure it gets out to the device
- // Due to ReadOnly permissions set on TESTRO should be a no-op
- int rc = mm_remove_pages( RELEASE, l_dataptr, PAGESIZE );
- if( rc )
- {
- TRACFCOMP( g_trac_pnor, "PnorRpTest::test_ReadOnlyTag> ERROR : error on RELEASE : rc=%X", rc );
- TS_FAIL( "PnorRpTest::test_ReadOnlyTag> ERROR : error on RELEASE" );
- }
+ int l_status = TASK_STATUS_EXITED_CLEAN;
+ PNOR::SectionId l_testroSecId = PNOR::TESTRO;
- // Get physical address of pnor section
- uint64_t l_address = 0;
- l_errhdl = PnorRP::getInstance().computeDeviceAddr((void*)l_info.vaddr,
- l_address,
- chip_select,
- needs_ecc);
- if(l_errhdl)
- {
- TRACFCOMP(g_trac_pnor, "PnorRpTest::test_ReadOnlyTag> ERROR : computeDeviceAddr vaddr = 0x%X",l_info.vaddr);
- errlCommit(l_errhdl,PNOR_COMP_ID);
- TS_FAIL( "PnorRpTest::test_ReadOnlyTag> ERROR : computeDeviceAddr vaddr = 0x%X",l_info.vaddr);
- }
+ printk("Test case: Expect to see uncaught exception! ");
+ tid_t l_childTask =
+ task_create(writeToReadOnlyPartition, &l_testroSecId);
- // Read pnor section and check if write did not occur
- uint64_t l_readData = 0;
- size_t l_size = sizeof(uint64_t);
- l_errhdl = deviceRead(TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL,
- &l_readData,
- l_size,
- DEVICE_PNOR_ADDRESS(0, l_address));
- TRACFCOMP(g_trac_pnor, "PnorRpTest::test_ReadOnlyTag> Read Data = 0x%X",l_readData);
- if(l_errhdl)
+ if((l_childTask != task_wait_tid(l_childTask, &l_status, nullptr)) ||
+ (l_status != TASK_STATUS_CRASHED))
{
- TS_FAIL("PnorRpTest::test_ReadOnlyTag: deviceRead() failed! Error committed.");
- ERRORLOG::errlCommit(l_errhdl, PNOR_COMP_ID);
- }
- if(l_readData == l_writeData)
- {
- TS_FAIL("PnorRpTest::test_ReadOnlyTag: Data was written to readOnly section = %s",
- l_info.name);
- }
- if(l_size != sizeof(uint64_t))
- {
- TS_FAIL("PnorRpTest::test_ReadOnlyTag: deviceRead() Read length not expected value. Addr: 0x%llx, Exp: %d, Act: %d",
- l_address, sizeof(uint64_t), l_size);
+ TS_FAIL("Write to readOnly partition exception not caught.");
}
- TRACFCOMP(g_trac_pnor, "PnorRpTest::test_ReadOnlyTag End");
+ TRACFCOMP(g_trac_pnor, "PnorRpTest::test_write_ReadOnly_partition End");
}
-
//@todo - import config data from build and compare to section info
/**
@@ -913,7 +885,97 @@ class PnorRpTest : public CxxTest::TestSuite
} while (0);
#endif
- }
+ }
+
+ private:
+ static void* readFromReadOnlyPartition(void* i_section)
+ {
+ TRACFCOMP(g_trac_pnor, "readFromReadOnlyPartition Start");
+ PNOR::SectionId* l_section =
+ reinterpret_cast<PNOR::SectionId*>(i_section);
+ PNOR::SectionInfo_t l_info;
+ errlHndl_t l_errhdl = nullptr;
+
+ do {
+
+ if(isEnforcedSecureSection(*l_section))
+ {
+ TS_FAIL("readFromReadOnlyPartition: section %d is secure."
+ " readFromReadOnlyPartition does not support testing"
+ " secure sections.", *l_section);
+ break;
+ }
+
+ l_errhdl = PNOR::getSectionInfo(*l_section, l_info);
+ if(l_errhdl)
+ {
+ TRACFCOMP(g_trac_pnor, "readFromReadOnlyPartition: getSectionInfo "
+ " returned an error for section %d : RC = 0x%.04x",
+ *l_section, l_errhdl->reasonCode());
+ ERRORLOG::errlCommit(l_errhdl, PNOR_COMP_ID);
+ TS_FAIL("readFromReadOnlyPartition: failed to getSectionInfo"
+ " for section %d", *l_section);
+ break;
+ }
+
+ uint64_t l_data = 0;
+ memcpy(&l_data, (void*)l_info.vaddr, sizeof(l_data));
+ // For this testing purpose, it doesn't actually matter what the data is
+ } while(0);
+ TRACFCOMP(g_trac_pnor, "readFromReadOnlyPartition End");
+ return nullptr;
+ }
+
+ static void* writeToReadOnlyPartition(void* i_section)
+ {
+ TRACFCOMP(g_trac_pnor, "writeToReadOnlyPartition Start");
+ PNOR::SectionId* l_section =
+ reinterpret_cast<PNOR::SectionId*>(i_section);
+ PNOR::SectionInfo_t l_info;
+ errlHndl_t l_errhdl = nullptr;
+
+ do {
+
+ if(isEnforcedSecureSection(*l_section))
+ {
+ TS_FAIL("writeToReadOnlyPartition: section %d is secure."
+ " writeToReadOnlyPartition does not support testing secure"
+ " sections.", *l_section);
+ break;
+ }
+
+ l_errhdl = PNOR::getSectionInfo(*l_section, l_info);
+ if(l_errhdl)
+ {
+ TRACFCOMP(g_trac_pnor, "writeToReadOnlyPartition:"
+ " getSectionInfo returned"
+ " an error for section %d : RC=0x%.04x",
+ *l_section, l_errhdl->reasonCode());
+ ERRORLOG::errlCommit(l_errhdl, PNOR_COMP_ID);
+ TS_FAIL("writeToReadOnlyPartition: could not read pnor section %d",
+ *l_section);
+ break;
+ }
+
+ // Write some data; should cause a task crash
+ const uint64_t l_writeData = 0x1122334455667788;
+ uint64_t* l_dataptr = reinterpret_cast<uint64_t*> (l_info.vaddr);
+ l_dataptr[0] = l_writeData;
+
+ int rc = mm_remove_pages(RELEASE, l_dataptr, PAGESIZE);
+ if(!rc)
+ {
+ TRACFCOMP(g_trac_pnor, "writeToReadOnlyPartition : uncaught "
+ "exception - write to a readOnly partition succeeded");
+ TS_FAIL("writeToReadOnlyPartition : no error returned on writing to"
+ " a readOnly partition");
+ break;
+ }
+
+ } while(0);
+ TRACFCOMP(g_trac_pnor, "writeToReadOnlyPartition End");
+ return nullptr;
+ }
};
diff --git a/src/usr/secureboot/base/test/securerommgrtest.H b/src/usr/secureboot/base/test/securerommgrtest.H
index 8ffa8375d..35e70f707 100644
--- a/src/usr/secureboot/base/test/securerommgrtest.H
+++ b/src/usr/secureboot/base/test/securerommgrtest.H
@@ -380,6 +380,16 @@ class SecureRomManagerTest : public CxxTest::TestSuite
- VFS::VfsRp::getInstance().iv_unprotectedOffset
+ l_vaddr;
memcpy(l_originPage, reinterpret_cast<uint8_t*>(l_pnorVaddr), PAGESIZE);
+ // Open the write permissions to allow the test to temporarily corrupt
+ // the partition.
+ int l_rc = mm_set_permission(reinterpret_cast<void*>(l_pnorVaddr),
+ 2*PAGESIZE,
+ WRITABLE);
+ if(l_rc)
+ {
+ TS_FAIL("mm_set_permission: Cannot set permissions to write");
+ break;
+ }
// Corrupt page
uint8_t l_corruptByte = 0xFF;
@@ -400,6 +410,16 @@ class SecureRomManagerTest : public CxxTest::TestSuite
delete l_errl;
l_errl = nullptr;
+ // Reset to read-only permissions.
+ l_rc = mm_set_permission(reinterpret_cast<void*>(l_pnorVaddr),
+ 2*PAGESIZE,
+ READ_ONLY);
+ if(l_rc)
+ {
+ TS_FAIL("mm_set_permission: Cannot reset permissions to read only");
+ break;
+ }
+
} while(0);
if ( signedFile_pageAddr != nullptr )
OpenPOWER on IntegriCloud