fru-device: Strengthen fru header check

We found a couple false positives, check header
more stringent.

Tested: All expected frus still exist, false positives
went away.

Change-Id: I56a6f148d895dc5d3dcdde8511f298594ff0af61
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/src/FruDevice.cpp b/src/FruDevice.cpp
index a8c6805..b98615d 100644
--- a/src/FruDevice.cpp
+++ b/src/FruDevice.cpp
@@ -113,6 +113,50 @@
     return i2c_smbus_read_i2c_block_data(file, high_addr, len, buf);
 }
 
+bool validateHeader(const std::array<uint8_t, I2C_SMBUS_BLOCK_MAX>& blockData)
+{
+    // ipmi spec format version number is currently at 1, verify it
+    if (blockData[0] != 0x1)
+    {
+        return false;
+    }
+
+    // verify pad is set to 0
+    if (blockData[6] != 0x0)
+    {
+        return false;
+    }
+
+    // verify offsets are 0, or don't point to another offset
+    std::set<uint8_t> foundOffsets;
+    for (int ii = 1; ii < 6; ii++)
+    {
+        if (blockData[ii] == 0)
+        {
+            continue;
+        }
+        auto [_, inserted] = foundOffsets.insert(blockData[ii]);
+        if (!inserted)
+        {
+            return false;
+        }
+    }
+
+    // validate checksum
+    size_t sum = 0;
+    for (int jj = 0; jj < 7; jj++)
+    {
+        sum += blockData[jj];
+    }
+    sum = (256 - sum) & 0xFF;
+
+    if (sum != blockData[7])
+    {
+        return false;
+    }
+    return true;
+}
+
 int get_bus_frus(int file, int first, int last, int bus,
                  std::shared_ptr<DeviceMap> devices)
 {
@@ -157,15 +201,9 @@
                           << "\n";
                 continue;
             }
-            size_t sum = 0;
-            for (int jj = 0; jj < 7; jj++)
-            {
-                sum += block_data[jj];
-            }
-            sum = (256 - sum) & 0xFF;
 
             // check the header checksum
-            if (sum == block_data[7])
+            if (validateHeader(block_data))
             {
                 std::vector<char> device;
                 device.insert(device.end(), block_data.begin(),
@@ -209,10 +247,10 @@
                 }
                 devices->emplace(ii, device);
             }
-            else
+            else if (DEBUG)
             {
-                std::cerr << "Illegal header checksum at bus " << bus
-                          << " address " << ii << "\n";
+                std::cerr << "Illegal header at bus " << bus << " address "
+                          << ii << "\n";
             }
         }
         return 1;