mirror of
https://github.com/espressif/openthread.git
synced 2026-08-30 13:59:54 +00:00
[network-data] add additional TLV length checks (#2154)
Credit to OSS-Fuzz.
This commit is contained in:
@@ -104,6 +104,8 @@ otError NetworkData::GetNextOnMeshPrefix(otNetworkDataIterator *aIterator, uint1
|
||||
BorderRouterTlv *borderRouter;
|
||||
BorderRouterEntry *borderRouterEntry = NULL;
|
||||
|
||||
VerifyOrExit(cur + sizeof(NetworkDataTlv) <= end && cur->GetNext() <= end, error = OT_ERROR_PARSE);
|
||||
|
||||
if (cur->GetType() != NetworkDataTlv::kTypePrefix)
|
||||
{
|
||||
continue;
|
||||
@@ -172,6 +174,8 @@ otError NetworkData::GetNextExternalRoute(otNetworkDataIterator *aIterator, uint
|
||||
HasRouteTlv *hasRoute;
|
||||
HasRouteEntry *hasRouteEntry = NULL;
|
||||
|
||||
VerifyOrExit(cur + sizeof(NetworkDataTlv) <= end && cur->GetNext() <= end, error = OT_ERROR_PARSE);
|
||||
|
||||
if (cur->GetType() != NetworkDataTlv::kTypePrefix)
|
||||
{
|
||||
continue;
|
||||
@@ -438,6 +442,8 @@ BorderRouterTlv *NetworkData::FindBorderRouter(PrefixTlv &aPrefix)
|
||||
|
||||
while (cur < end)
|
||||
{
|
||||
VerifyOrExit(cur + sizeof(NetworkDataTlv) <= end && cur->GetNext() <= end);
|
||||
|
||||
if (cur->GetType() == NetworkDataTlv::kTypeBorderRouter)
|
||||
{
|
||||
ExitNow(rval = reinterpret_cast<BorderRouterTlv *>(cur));
|
||||
@@ -458,6 +464,8 @@ BorderRouterTlv *NetworkData::FindBorderRouter(PrefixTlv &aPrefix, bool aStable)
|
||||
|
||||
while (cur < end)
|
||||
{
|
||||
VerifyOrExit(cur + sizeof(NetworkDataTlv) <= end && cur->GetNext() <= end);
|
||||
|
||||
if (cur->GetType() == NetworkDataTlv::kTypeBorderRouter &&
|
||||
cur->IsStable() == aStable)
|
||||
{
|
||||
@@ -479,6 +487,8 @@ HasRouteTlv *NetworkData::FindHasRoute(PrefixTlv &aPrefix)
|
||||
|
||||
while (cur < end)
|
||||
{
|
||||
VerifyOrExit(cur + sizeof(NetworkDataTlv) <= end && cur->GetNext() <= end);
|
||||
|
||||
if (cur->GetType() == NetworkDataTlv::kTypeHasRoute)
|
||||
{
|
||||
ExitNow(rval = reinterpret_cast<HasRouteTlv *>(cur));
|
||||
@@ -499,6 +509,8 @@ HasRouteTlv *NetworkData::FindHasRoute(PrefixTlv &aPrefix, bool aStable)
|
||||
|
||||
while (cur < end)
|
||||
{
|
||||
VerifyOrExit(cur + sizeof(NetworkDataTlv) <= end && cur->GetNext() <= end);
|
||||
|
||||
if (cur->GetType() == NetworkDataTlv::kTypeHasRoute &&
|
||||
cur->IsStable() == aStable)
|
||||
{
|
||||
@@ -520,6 +532,8 @@ ContextTlv *NetworkData::FindContext(PrefixTlv &aPrefix)
|
||||
|
||||
while (cur < end)
|
||||
{
|
||||
VerifyOrExit(cur + sizeof(NetworkDataTlv) <= end && cur->GetNext() <= end);
|
||||
|
||||
if (cur->GetType() == NetworkDataTlv::kTypeContext)
|
||||
{
|
||||
ExitNow(rval = reinterpret_cast<ContextTlv *>(cur));
|
||||
@@ -545,6 +559,8 @@ PrefixTlv *NetworkData::FindPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength
|
||||
|
||||
while (cur < end)
|
||||
{
|
||||
VerifyOrExit(cur + sizeof(NetworkDataTlv) <= end && cur->GetNext() <= end);
|
||||
|
||||
if (cur->GetType() == NetworkDataTlv::kTypePrefix)
|
||||
{
|
||||
compare = reinterpret_cast<PrefixTlv *>(cur);
|
||||
@@ -559,6 +575,7 @@ PrefixTlv *NetworkData::FindPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength
|
||||
cur = cur->GetNext();
|
||||
}
|
||||
|
||||
exit:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -414,8 +414,9 @@ exit:
|
||||
}
|
||||
}
|
||||
|
||||
void Leader::RlocLookup(uint16_t aRloc16, bool &aIn, bool &aStable, uint8_t *aTlvs, uint8_t aTlvsLength)
|
||||
otError Leader::RlocLookup(uint16_t aRloc16, bool &aIn, bool &aStable, uint8_t *aTlvs, uint8_t aTlvsLength)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
NetworkDataTlv *cur = reinterpret_cast<NetworkDataTlv *>(aTlvs);
|
||||
NetworkDataTlv *end = reinterpret_cast<NetworkDataTlv *>(aTlvs + aTlvsLength);
|
||||
NetworkDataTlv *subCur;
|
||||
@@ -428,14 +429,21 @@ void Leader::RlocLookup(uint16_t aRloc16, bool &aIn, bool &aStable, uint8_t *aTl
|
||||
|
||||
while (cur < end)
|
||||
{
|
||||
VerifyOrExit(cur + sizeof(NetworkDataTlv) <= end && cur->GetNext() <= end, error = OT_ERROR_PARSE);
|
||||
|
||||
if (cur->GetType() == NetworkDataTlv::kTypePrefix)
|
||||
{
|
||||
prefix = static_cast<PrefixTlv *>(cur);
|
||||
subCur = prefix->GetSubTlvs();
|
||||
subEnd = prefix->GetNext();
|
||||
|
||||
VerifyOrExit(subEnd <= end, error = OT_ERROR_PARSE);
|
||||
|
||||
while (subCur < subEnd)
|
||||
{
|
||||
VerifyOrExit(subCur + sizeof(NetworkDataTlv) <= subEnd && subCur->GetNext() <= subEnd,
|
||||
error = OT_ERROR_PARSE);
|
||||
|
||||
switch (subCur->GetType())
|
||||
{
|
||||
case NetworkDataTlv::kTypeBorderRouter:
|
||||
@@ -495,7 +503,7 @@ void Leader::RlocLookup(uint16_t aRloc16, bool &aIn, bool &aStable, uint8_t *aTl
|
||||
}
|
||||
|
||||
exit:
|
||||
return;
|
||||
return error;
|
||||
}
|
||||
|
||||
bool Leader::IsStableUpdated(uint16_t aRloc16, uint8_t *aTlvs, uint8_t aTlvsLength, uint8_t *aTlvsBase,
|
||||
@@ -507,6 +515,8 @@ bool Leader::IsStableUpdated(uint16_t aRloc16, uint8_t *aTlvs, uint8_t aTlvsLeng
|
||||
|
||||
while (cur < end)
|
||||
{
|
||||
VerifyOrExit(cur + sizeof(NetworkDataTlv) <= end && cur->GetNext() <= end);
|
||||
|
||||
if (cur->GetType() == NetworkDataTlv::kTypePrefix)
|
||||
{
|
||||
PrefixTlv *prefix = static_cast<PrefixTlv *>(cur);
|
||||
@@ -583,7 +593,7 @@ otError Leader::RegisterNetworkData(uint16_t aRloc16, uint8_t *aTlvs, uint8_t aT
|
||||
}
|
||||
else
|
||||
{
|
||||
RlocLookup(aRloc16, rlocIn, rlocStable, aTlvs, aTlvsLength);
|
||||
SuccessOrExit(error = RlocLookup(aRloc16, rlocIn, rlocStable, aTlvs, aTlvsLength));
|
||||
SuccessOrExit(error = AddNetworkData(aTlvs, aTlvsLength));
|
||||
|
||||
mVersion++;
|
||||
@@ -602,11 +612,14 @@ exit:
|
||||
|
||||
otError Leader::AddNetworkData(uint8_t *aTlvs, uint8_t aTlvsLength)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
NetworkDataTlv *cur = reinterpret_cast<NetworkDataTlv *>(aTlvs);
|
||||
NetworkDataTlv *end = reinterpret_cast<NetworkDataTlv *>(aTlvs + aTlvsLength);
|
||||
|
||||
while (cur < end)
|
||||
{
|
||||
VerifyOrExit(cur + sizeof(NetworkDataTlv) <= end && cur->GetNext() <= end, error = OT_ERROR_NONE);
|
||||
|
||||
switch (cur->GetType())
|
||||
{
|
||||
case NetworkDataTlv::kTypePrefix:
|
||||
@@ -623,16 +636,20 @@ otError Leader::AddNetworkData(uint8_t *aTlvs, uint8_t aTlvsLength)
|
||||
|
||||
otDumpDebgNetData(GetInstance(), "add done", mTlvs, mLength);
|
||||
|
||||
return OT_ERROR_NONE;
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError Leader::AddPrefix(PrefixTlv &aPrefix)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
NetworkDataTlv *cur = aPrefix.GetSubTlvs();
|
||||
NetworkDataTlv *end = aPrefix.GetNext();
|
||||
|
||||
while (cur < end)
|
||||
{
|
||||
VerifyOrExit(cur + sizeof(NetworkDataTlv) <= end && cur->GetNext() <= end, error = OT_ERROR_NONE);
|
||||
|
||||
switch (cur->GetType())
|
||||
{
|
||||
case NetworkDataTlv::kTypeHasRoute:
|
||||
@@ -650,7 +667,8 @@ otError Leader::AddPrefix(PrefixTlv &aPrefix)
|
||||
cur = cur->GetNext();
|
||||
}
|
||||
|
||||
return OT_ERROR_NONE;
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError Leader::AddHasRoute(PrefixTlv &aPrefix, HasRouteTlv &aHasRoute)
|
||||
|
||||
@@ -168,7 +168,7 @@ private:
|
||||
otError RemoveRloc(PrefixTlv &aPrefix, HasRouteTlv &aHasRoute, uint16_t aRloc16);
|
||||
otError RemoveRloc(PrefixTlv &aPrefix, BorderRouterTlv &aBorderRouter, uint16_t aRloc16);
|
||||
|
||||
void RlocLookup(uint16_t aRloc16, bool &aIn, bool &aStable, uint8_t *aTlvs, uint8_t aTlvsLength);
|
||||
otError RlocLookup(uint16_t aRloc16, bool &aIn, bool &aStable, uint8_t *aTlvs, uint8_t aTlvsLength);
|
||||
bool IsStableUpdated(uint16_t aRloc16, uint8_t *aTlvs, uint8_t aTlvsLength, uint8_t *aTlvsBase,
|
||||
uint8_t aTlvsBaseLength);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user