Skip to content

Commit

Permalink
Fix oss-fuzz issue 64111 (#1237)
Browse files Browse the repository at this point in the history
  • Loading branch information
sashashura authored Nov 15, 2023
1 parent 452a53a commit 9fbc712
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 3 deletions.
8 changes: 8 additions & 0 deletions Packet++/header/BgpLayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,14 @@ class BgpUpdateMessageLayer : public BgpLayer
*/
BgpUpdateMessageLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) : BgpLayer(data, dataLen, prevLayer, packet) {}

/**
* A static method that takes a byte array and detects whether it is a BgpUpdateMessage
* @param[in] data A byte array
* @param[in] dataSize The byte array size (in bytes)
* @return True if the data looks like a valid BgpUpdateMessage layer
*/
static bool isDataValid(const uint8_t *data, size_t dataSize);

/**
* A c'tor that creates a new BGP UPDATE message
* @param[in] withdrawnRoutes A vector of withdrawn routes data. If left empty (which is the default value) no withdrawn route information will be written to the message
Expand Down
23 changes: 20 additions & 3 deletions Packet++/src/BgpLayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,22 @@ size_t BgpLayer::getHeaderLen() const

BgpLayer* BgpLayer::parseBgpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
{
if (dataLen < sizeof(bgp_common_header))
if (data == nullptr || dataLen < sizeof(bgp_common_header))
return nullptr;

bgp_common_header* bgpHeader = (bgp_common_header*)data;

// illegal header data - length is too small
if (be16toh(bgpHeader->length) < static_cast<uint16_t>(sizeof(bgp_common_header)))
uint16_t messageLen = be16toh(bgpHeader->length);
if (dataLen < messageLen || messageLen < static_cast<uint16_t>(sizeof(bgp_common_header)))
return nullptr;

switch (bgpHeader->messageType)
{
case 1: // OPEN
return new BgpOpenMessageLayer(data, dataLen, prevLayer, packet);
case 2: // UPDATE
return new BgpUpdateMessageLayer(data, dataLen, prevLayer, packet);
return BgpUpdateMessageLayer::isDataValid(data, dataLen) ? new BgpUpdateMessageLayer(data, dataLen, prevLayer, packet) : nullptr;
case 3: // NOTIFICATION
return new BgpNotificationMessageLayer(data, dataLen, prevLayer, packet);
case 4: // KEEPALIVE
Expand Down Expand Up @@ -703,6 +704,22 @@ void BgpUpdateMessageLayer::getNetworkLayerReachabilityInfo(std::vector<prefix_a
parsePrefixAndIPData(dataPtr, nlriSize, nlri);
}

bool BgpUpdateMessageLayer::isDataValid(const uint8_t *data, size_t dataSize)
{
if (dataSize < sizeof(bgp_common_header) + 2*sizeof(uint16_t))
return false;

uint16_t withdrLen = be16toh(*(uint16_t*)(data + sizeof(bgp_common_header)));
if (dataSize < sizeof(bgp_common_header) + 2*sizeof(uint16_t) + withdrLen)
return false;

uint16_t attrLen = be16toh(*(uint16_t*)(data + sizeof(bgp_common_header) + sizeof(uint16_t) + withdrLen));
if (dataSize < sizeof(bgp_common_header) + 2*sizeof(uint16_t) + withdrLen + attrLen)
return false;

return true;
}

bool BgpUpdateMessageLayer::setNetworkLayerReachabilityInfo(const std::vector<prefix_and_ip>& nlri)
{
uint8_t newNlriData[1500];
Expand Down

0 comments on commit 9fbc712

Please sign in to comment.