summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOskar Senft <osk@google.com>2018-12-04 13:53:16 -0500
committerOskar Senft <osk@google.com>2019-02-11 18:22:28 +0000
commit8f51109d8ecd3a396e935a9705b452fdb11cc614 (patch)
treec58464df696dc52b2862e54e433a820213b613e2
parent695408618ed50ba886080b898aa77b980589ee4c (diff)
downloadipmi-fru-parser-8f51109d8ecd3a396e935a9705b452fdb11cc614.zip
ipmi-fru-parser-8f51109d8ecd3a396e935a9705b452fdb11cc614.tar.gz
readeeprom: Allow FRU ID 0 to be selected
We incorrectly checked that FRU ID != 0, which is the default FRU ID. Actually, the IPMI spec specifies FRU ID 0xff as reserved, so the check was changed to prevent that ID from being used instead. Split out fruid parsing code to its own function to cover various edge and failure cases. Tested: Ran 'phosphor-read-eeprom --eeprom fru.bin --fruid=0' and checked that values are reported to inventory as expected. Ran with '--fruid=ff' ('invalid' FRU ID): rejected Ran with '--fruid=xx' (non-HEX FRU ID): rejected Ran with '--fruid=100' (out-of-range FRU ID): rejected Ran with '--fruid="0 0"' (invalid number): rejected Ran with '--fruid=10.0' (non-integer): rejected Ran with '--fruid=0x12' (valid HEX FRU ID): accepted Ran with '--fruid=fe' (valid HEX FRU ID): accepted Change-Id: Ic1fb79cefc6931f21d0b5cb4363ad5fd44f47c92 Signed-off-by: Oskar Senft <osk@google.com>
-rw-r--r--readeeprom.cpp47
1 files changed, 40 insertions, 7 deletions
diff --git a/readeeprom.cpp b/readeeprom.cpp
index d518a83..f5fa148 100644
--- a/readeeprom.cpp
+++ b/readeeprom.cpp
@@ -17,13 +17,51 @@ static void exit_with_error(const char* err, char** argv)
exit(-1);
}
+static uint8_t parse_fruid_or_exit(const char* fruid_str, char** argv)
+{
+ const uint8_t MAX_FRU_ID = 0xfe;
+ unsigned long fruid;
+ char* endptr = NULL;
+
+ // The FRUID string must not be empty.
+ if (fruid_str == nullptr || *fruid_str == '\0')
+ {
+ exit_with_error("Empty fruid.", argv);
+ }
+
+ errno = 0;
+ fruid = std::strtoul(fruid_str, &endptr, 16);
+
+ // Handle error cases
+ if (errno == ERANGE)
+ {
+ exit_with_error("fruid is out of range.", argv);
+ }
+ if (errno != 0)
+ {
+ exit_with_error("Could not parse fruid.", argv);
+ }
+ if (*endptr != '\0')
+ {
+ // The string was not fully parsed, e.g. contains invalid characters
+ exit_with_error("Invalid fruid.", argv);
+ }
+ if (fruid > MAX_FRU_ID)
+ {
+ // The string was parsed, but the set FRUID is too large.
+ exit_with_error("fruid is out of range.", argv);
+ }
+
+ return fruid;
+}
+
//--------------------------------------------------------------------------
// This gets called by udev monitor soon after seeing hog plugs for EEPROMS.
//--------------------------------------------------------------------------
int main(int argc, char** argv)
{
int rc = 0;
- uint8_t fruid = 0;
+ uint8_t fruid;
// Read the arguments.
auto cli_options = std::make_unique<ArgumentParser>(argc, argv);
@@ -44,12 +82,7 @@ int main(int argc, char** argv)
}
// Extract the fruid
- fruid = std::strtol(fruid_str.c_str(), NULL, 16);
- if (fruid == 0)
- {
- // User has not passed in the appropriate argument value
- exit_with_error("Invalid fruid.", argv);
- }
+ fruid = parse_fruid_or_exit(fruid_str.c_str(), argv);
// Finished getting options out, so release the parser.
cli_options.release();
OpenPOWER on IntegriCloud