diff --git a/Packet++/header/SomeIpSdLayer.h b/Packet++/header/SomeIpSdLayer.h index 2cf24162f1..551cacc037 100644 --- a/Packet++/header/SomeIpSdLayer.h +++ b/Packet++/header/SomeIpSdLayer.h @@ -662,6 +662,14 @@ class SomeIpSdLayer : public SomeIpLayer */ static bool isSomeIpSdPort(uint16_t port) { return port == 30490; } + /** + * The static method makes validation of input data + * @param[in] data The pointer to the beginning of byte stream of IP packet + * @param[in] dataLen The length of byte stream + * @return True if the data is valid and can represent the packet + */ + static bool isDataValid(const uint8_t* data, size_t dataLen); + /** * Get the Flags of the layer * @return uint8_t Flags @@ -759,6 +767,7 @@ class SomeIpSdLayer : public SomeIpLayer bool addOptionIndex(uint32_t indexEntry, uint32_t indexOffset); OptionPtr parseOption(SomeIpSdOption::OptionType type, size_t offset) const; + static size_t getLenEntries(const uint8_t* data); size_t getLenEntries() const; size_t getLenOptions() const; void setLenEntries(uint32_t length); diff --git a/Packet++/src/SomeIpLayer.cpp b/Packet++/src/SomeIpLayer.cpp index bcf002e624..f97c006a44 100644 --- a/Packet++/src/SomeIpLayer.cpp +++ b/Packet++/src/SomeIpLayer.cpp @@ -79,7 +79,7 @@ Layer* SomeIpLayer::parseSomeIpLayer(uint8_t *data, size_t dataLen, Layer* prevL return new PayloadLayer(data, dataLen, prevLayer, packet); } - if (be16toh(hdr->serviceID) == 0xFFFF && be16toh(hdr->methodID) == 0x8100) + if (be16toh(hdr->serviceID) == 0xFFFF && be16toh(hdr->methodID) == 0x8100 && SomeIpSdLayer::isDataValid(data, dataLen)) { return new SomeIpSdLayer(data, dataLen, prevLayer, packet); } diff --git a/Packet++/src/SomeIpSdLayer.cpp b/Packet++/src/SomeIpSdLayer.cpp index de21de8a6f..cf3a749d53 100644 --- a/Packet++/src/SomeIpSdLayer.cpp +++ b/Packet++/src/SomeIpSdLayer.cpp @@ -631,6 +631,20 @@ uint32_t SomeIpSdLayer::addEntry(const SomeIpSdEntry &entry) return getNumEntries() - 1; } +bool SomeIpSdLayer::isDataValid(const uint8_t* data, size_t dataLen) +{ + if (!data) + return false; + + if (dataLen < (sizeof(someipsdhdr) + sizeof(uint32_t))) + return false; + + if (dataLen < (sizeof(someipsdhdr) + sizeof(uint32_t) + getLenEntries(data))) + return false; + + return true; +} + uint32_t SomeIpSdLayer::countOptions() { size_t offsetOption = sizeof(someipsdhdr) + sizeof(uint32_t) + getLenEntries() + sizeof(uint32_t); @@ -768,7 +782,12 @@ SomeIpSdLayer::OptionPtr SomeIpSdLayer::parseOption(SomeIpSdOption::OptionType t size_t SomeIpSdLayer::getLenEntries() const { - return be32toh(*((uint32_t *)(m_Data + sizeof(someipsdhdr)))); + return getLenEntries(m_Data); +} + +size_t SomeIpSdLayer::getLenEntries(const uint8_t* data) +{ + return be32toh(*((uint32_t *)(data + sizeof(someipsdhdr)))); } size_t SomeIpSdLayer::getLenOptions() const diff --git a/Tests/Fuzzers/RegressionTests/regression_samples/clusterfuzz-testcase-minimized-FuzzTarget-5124308624343040 b/Tests/Fuzzers/RegressionTests/regression_samples/clusterfuzz-testcase-minimized-FuzzTarget-5124308624343040 new file mode 100644 index 0000000000..20e45d816b Binary files /dev/null and b/Tests/Fuzzers/RegressionTests/regression_samples/clusterfuzz-testcase-minimized-FuzzTarget-5124308624343040 differ