diff options
author | lixg <867314078@qq.com> | 2019-09-21 02:30:21 +0000 |
---|---|---|
committer | Daniel M Crowell <dcrowell@us.ibm.com> | 2019-10-03 13:33:52 -0500 |
commit | ba790597aecf510026596b94822916deecb488fd (patch) | |
tree | c319c43fbd66fbe0ea6ba3507be3ee74b06471f6 | |
parent | c79620afdf079771a186d22743e19596ddada22d (diff) | |
download | talos-hostboot-ba790597aecf510026596b94822916deecb488fd.tar.gz talos-hostboot-ba790597aecf510026596b94822916deecb488fd.zip |
Verify manufacture date (MB) from PVPD before using
If the contents of the MB keyword is invalid, we could end
up doing some illegal math and causing a crash. This change
will add some simple verification of the data before we use
it.
Resolves #183
Change-Id: I2f3ead87be24e909a671f54f6005f3fffdbafd52
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/84441
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>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Matt Derksen <mderkse1@us.ibm.com>
Reviewed-by: William G Hoffa <wghoffa@us.ibm.com>
Reviewed-by: Daniel M Crowell <dcrowell@us.ibm.com>
-rw-r--r-- | src/usr/ipmiext/ipmifruinv.C | 92 |
1 files changed, 57 insertions, 35 deletions
diff --git a/src/usr/ipmiext/ipmifruinv.C b/src/usr/ipmiext/ipmifruinv.C index a41d67394..14ad957d1 100644 --- a/src/usr/ipmiext/ipmifruinv.C +++ b/src/usr/ipmiext/ipmifruinv.C @@ -9,6 +9,7 @@ /* [+] International Business Machines Corp. */ /* [+] Super Micro Computer, Inc. */ /* [+] YADRO */ +/* [+] lixg */ /* */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); */ @@ -546,42 +547,43 @@ errlHndl_t IpmiFruInv::formatMfgData(std::vector<uint8_t> i_mfgDateData, { errlHndl_t l_errl = NULL; - // MB keyword size is 8 hex bytes, throw an error if it is smaller so we - // don't do an invalid access. - if (i_mfgDateData.size() != 8) + do { - /*@ - * @errortype - * @moduleid IPMI::MOD_IPMIFRU_INV - * @reasoncode IPMI::RC_INVALID_VPD_DATA - * @userdata1 Size of vpd data - * - * @devdesc VPD data is invalid size - */ - l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_INFORMATIONAL, - IPMI::MOD_IPMIFRU_INV, - IPMI::RC_INVALID_VPD_DATA, - i_mfgDateData.size()); - - TARGETING::Target* nodeTarget = NULL; - TARGETING::PredicateCTM nodeFilter(TARGETING::CLASS_ENC, - TARGETING::TYPE_NODE); - TARGETING::TargetRangeFilter nodeItr( - TARGETING::targetService().begin(), - TARGETING::targetService().end(), - &nodeFilter); - - nodeTarget = *nodeItr; - - // Callout out node since that is where the VPD lives - l_errl->addHwCallout(nodeTarget, - HWAS::SRCI_PRIORITY_HIGH, - HWAS::NO_DECONFIG, - HWAS::GARD_NULL ); + // MB keyword size is 8 hex bytes, throw an error if it is smaller so we + // don't do an invalid access. + if (i_mfgDateData.size() != 8) + { + /*@ + * @errortype + * @moduleid IPMI::MOD_IPMIFRU_INV + * @reasoncode IPMI::RC_INVALID_VPD_DATA + * @userdata1 Size of vpd data + * + * @devdesc VPD data is invalid size + */ + l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_INFORMATIONAL, + IPMI::MOD_IPMIFRU_INV, + IPMI::RC_INVALID_VPD_DATA, + i_mfgDateData.size()); + + TARGETING::Target* nodeTarget = NULL; + TARGETING::PredicateCTM nodeFilter(TARGETING::CLASS_ENC, + TARGETING::TYPE_NODE); + TARGETING::TargetRangeFilter nodeItr( + TARGETING::targetService().begin(), + TARGETING::targetService().end(), + &nodeFilter); + + nodeTarget = *nodeItr; + + // Callout out node since that is where the VPD lives + l_errl->addHwCallout(nodeTarget, + HWAS::SRCI_PRIORITY_HIGH, + HWAS::NO_DECONFIG, + HWAS::GARD_NULL ); + break; + } - } - else - { // Convert Centuries / Years / months / day / hour / minute / second // into a uint64 representing number of minute since 1/1/96 @@ -594,6 +596,25 @@ errlHndl_t IpmiFruInv::formatMfgData(std::vector<uint8_t> i_mfgDateData, uint8_t hour = bcd2_to_int(i_mfgDateData.at(5)); uint8_t minute = bcd2_to_int(i_mfgDateData.at(6)); + // Do some sanity checking on the data so the math below doesn't + // go crazy and cause a crash + if ( (century < 20) + || (month < 1) || (month > 12) + || (day < 1) || (day > 31) + || (hour > 23) || (minute > 59) ) + { + o_mfgDate = 0xFFFFFFFF; + TRACFCOMP(g_trac_ipmi,"MfgDate error: %02X %02X %02X %02X %02X %02X %02X ", + i_mfgDateData.at(0), + i_mfgDateData.at(1), + i_mfgDateData.at(2), + i_mfgDateData.at(3), + i_mfgDateData.at(4), + i_mfgDateData.at(5), + i_mfgDateData.at(6)); + break; + } + // Subtract year uint8_t numOfYears = (century*100 + year) - 1996; // Subtract month @@ -612,6 +633,7 @@ errlHndl_t IpmiFruInv::formatMfgData(std::vector<uint8_t> i_mfgDateData, // Add a day for every leap year // Check if we need to consider the current year + // Year is related to century, anybody familiar with this may fix it if (month <= 2) { // We don't need to consider this year for a leap year, as it @@ -638,7 +660,7 @@ errlHndl_t IpmiFruInv::formatMfgData(std::vector<uint8_t> i_mfgDateData, // Convert into minutes o_mfgDate = (((numOfDays*24)*60) + (hour*60) + minute); - } + } while(0); return l_errl; } |