[mle] fix MleRouter::HandleChildUpdateResponse msg validation (#4297)

This commit moves the message security check to the top of
MleRouter::HandleChildUpdateResponse.
This commit is contained in:
Jonathan Hui
2019-11-06 07:02:19 -08:00
parent 779b7851bf
commit de8033fad4
4 changed files with 28 additions and 24 deletions
+1 -1
View File
@@ -2820,7 +2820,7 @@ void Mle::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageIn
case Header::kCommandChildUpdateResponse:
if (mRole == OT_DEVICE_ROLE_LEADER || mRole == OT_DEVICE_ROLE_ROUTER)
{
Get<MleRouter>().HandleChildUpdateResponse(aMessage, aMessageInfo, keySequence);
Get<MleRouter>().HandleChildUpdateResponse(aMessage, aMessageInfo, keySequence, neighbor);
}
else
{
+21 -21
View File
@@ -2370,11 +2370,11 @@ exit:
otError MleRouter::HandleChildUpdateResponse(const Message & aMessage,
const Ip6::MessageInfo &aMessageInfo,
uint32_t aKeySequence)
uint32_t aKeySequence,
Neighbor * aNeighbor)
{
otError error = OT_ERROR_NONE;
const otThreadLinkInfo *linkInfo = static_cast<const otThreadLinkInfo *>(aMessageInfo.GetLinkInfo());
Mac::ExtAddress macAddr;
SourceAddressTlv sourceAddress;
TimeoutTlv timeout;
ResponseTlv response;
@@ -2385,17 +2385,28 @@ otError MleRouter::HandleChildUpdateResponse(const Message & aMessage,
Child * child;
uint16_t addressRegistrationOffset = 0;
// Find Child
aMessageInfo.GetPeerAddr().ToExtAddress(macAddr);
child = mChildTable.FindChild(macAddr, ChildTable::kInStateAnyExceptInvalid);
if (child == NULL)
if ((aNeighbor == NULL) || IsActiveRouter(aNeighbor->GetRloc16()))
{
LogMleMessage("Receive Child Update Response from unknown child", aMessageInfo.GetPeerAddr());
ExitNow(error = OT_ERROR_NOT_FOUND);
}
child = static_cast<Child *>(aNeighbor);
// Response
if (Tlv::GetTlv(aMessage, Tlv::kResponse, sizeof(response), response) == OT_ERROR_NONE)
{
VerifyOrExit(response.IsValid() &&
memcmp(response.GetResponse(), child->GetChallenge(), child->GetChallengeSize()) == 0,
error = OT_ERROR_SECURITY);
}
else
{
VerifyOrExit(child->IsStateValid(), error = OT_ERROR_SECURITY);
}
LogMleMessage("Receive Child Update Response from child", aMessageInfo.GetPeerAddr(), child->GetRloc16());
// Source Address
if (Tlv::GetTlv(aMessage, Tlv::kSourceAddress, sizeof(sourceAddress), sourceAddress) == OT_ERROR_NONE)
{
@@ -2403,22 +2414,11 @@ otError MleRouter::HandleChildUpdateResponse(const Message & aMessage,
if (child->GetRloc16() != sourceAddress.GetRloc16())
{
LogMleMessage("Receive Child Update Response from unknown child", aMessageInfo.GetPeerAddr(),
sourceAddress.GetRloc16());
ExitNow(error = OT_ERROR_PARSE);
RemoveNeighbor(*child);
ExitNow();
}
}
LogMleMessage("Receive Child Update Response from child", aMessageInfo.GetPeerAddr(), child->GetRloc16());
// Response
if (Tlv::GetTlv(aMessage, Tlv::kResponse, sizeof(response), response) == OT_ERROR_NONE)
{
VerifyOrExit(response.IsValid() &&
memcmp(response.GetResponse(), child->GetChallenge(), child->GetChallengeSize()) == 0,
error = OT_ERROR_SECURITY);
}
// Status
if (Tlv::GetTlv(aMessage, Tlv::kStatus, sizeof(status), status) == OT_ERROR_NONE)
{
+2 -1
View File
@@ -691,7 +691,8 @@ private:
uint32_t aKeySequence);
otError HandleChildUpdateResponse(const Message & aMessage,
const Ip6::MessageInfo &aMessageInfo,
uint32_t aKeySequence);
uint32_t aKeySequence,
Neighbor * aNeighbor);
otError HandleDataRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
void HandleNetworkDataUpdateRouter(void);
otError HandleDiscoveryRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
+4 -1
View File
@@ -137,7 +137,10 @@ private:
otError HandleParentRequest(const Message &, const Ip6::MessageInfo &) { return OT_ERROR_DROP; }
otError HandleChildIdRequest(const Message &, const Ip6::MessageInfo &, uint32_t) { return OT_ERROR_DROP; }
otError HandleChildUpdateRequest(const Message &, const Ip6::MessageInfo &, uint32_t) { return OT_ERROR_DROP; }
otError HandleChildUpdateResponse(const Message &, const Ip6::MessageInfo &, uint32_t) { return OT_ERROR_DROP; }
otError HandleChildUpdateResponse(const Message &, const Ip6::MessageInfo &, uint32_t, Neighbor *)
{
return OT_ERROR_DROP;
}
otError HandleDataRequest(const Message &, const Ip6::MessageInfo &) { return OT_ERROR_DROP; }
void HandleNetworkDataUpdateRouter(void) {}
otError HandleDiscoveryRequest(const Message &, const Ip6::MessageInfo &) { return OT_ERROR_DROP; }