FruDevice: Verify offset overlap
Checking each field area offset if they are overlapping with
other field area offset.
Signed-off-by: Vijay Khemka <vijaykhemkalinux@gmail.com>
Change-Id: Id0fcb704ac20083fae1760ec7d6e6cb559442526
diff --git a/src/FruDevice.cpp b/src/FruDevice.cpp
index a48854c..ffae574 100644
--- a/src/FruDevice.cpp
+++ b/src/FruDevice.cpp
@@ -789,6 +789,81 @@
}
}
+/* This function verifies for other offsets to check if they are not
+ * falling under other field area
+ *
+ * fruBytes: Start of Fru data
+ * currentArea: Index of current area offset to be compared against all area
+ * offset and it is a multiple of 8 bytes as per specification
+ * len: Length of current area space and it is a multiple of 8 bytes
+ * as per specification
+ */
+static bool verifyOffset(const std::vector<uint8_t>& fruBytes,
+ fruAreas currentArea, uint8_t len)
+{
+
+ unsigned int fruBytesSize = fruBytes.size();
+
+ // check if Fru data has at least 8 byte header
+ if (fruBytesSize <= fruBlockSize)
+ {
+ std::cerr << "Error: trying to parse empty FRU\n";
+ return false;
+ }
+
+ // Check range of passed currentArea value
+ if (currentArea > fruAreas::fruAreaMultirecord)
+ {
+ std::cerr << "Error: Fru area is out of range\n";
+ return false;
+ }
+
+ unsigned int currentAreaIndex = getHeaderAreaFieldOffset(currentArea);
+ if (currentAreaIndex > fruBytesSize)
+ {
+ std::cerr << "Error: Fru area index is out of range\n";
+ return false;
+ }
+
+ unsigned int start = fruBytes[currentAreaIndex];
+ unsigned int end = start + len;
+
+ /* Verify each offset within the range of start and end */
+ for (fruAreas area = fruAreas::fruAreaInternal;
+ area <= fruAreas::fruAreaMultirecord; ++area)
+ {
+ // skip the current offset
+ if (area == currentArea)
+ {
+ continue;
+ }
+
+ unsigned int areaIndex = getHeaderAreaFieldOffset(area);
+ if (areaIndex > fruBytesSize)
+ {
+ std::cerr << "Error: Fru area index is out of range\n";
+ return false;
+ }
+
+ unsigned int areaOffset = fruBytes[areaIndex];
+ // if areaOffset is 0 means this area is not available so skip
+ if (areaOffset == 0)
+ {
+ continue;
+ }
+
+ // check for overlapping of current offset with given areaoffset
+ if (areaOffset == start || (areaOffset > start && areaOffset < end))
+ {
+ std::cerr << getFruAreaName(currentArea)
+ << " offset is overlapping with " << getFruAreaName(area)
+ << " offset\n";
+ return false;
+ }
+ }
+ return true;
+}
+
resCodes formatFRU(const std::vector<uint8_t>& fruBytes,
boost::container::flat_map<std::string, std::string>& result)
{
@@ -828,6 +903,15 @@
return resCodes::resErr;
}
++fruBytesIter;
+
+ /* Verify other area offset for overlap with current area by passing
+ * length of current area offset pointed by *fruBytesIter
+ */
+ if (!verifyOffset(fruBytes, area, *fruBytesIter))
+ {
+ return resCodes::resErr;
+ }
+
uint8_t fruAreaSize = *fruBytesIter * fruBlockSize;
std::vector<uint8_t>::const_iterator fruBytesIterEndArea =
fruBytes.begin() + offset + fruAreaSize - 1;