From b43d83f43f6ac4f5020cd0533d34f21ccc4842c4 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Wed, 19 Sep 2018 10:55:21 -0700 Subject: [PATCH] [network-data] check and validate received network data before registering (#3078) This commit adds check in `Leader::RegisterNetworkData()`to validate the received network data and ensure it only contains entries matching the RLOC16 of the device registering the network data. It updates `RlocLookup()` method to add a new mode to allow or not allow any entries that do not match the given RLOC16. --- src/core/thread/network_data_leader_ftd.cpp | 27 ++++++++++++++++----- src/core/thread/network_data_leader_ftd.hpp | 3 ++- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/core/thread/network_data_leader_ftd.cpp b/src/core/thread/network_data_leader_ftd.cpp index d2d80b51d..71a12460b 100644 --- a/src/core/thread/network_data_leader_ftd.cpp +++ b/src/core/thread/network_data_leader_ftd.cpp @@ -438,7 +438,8 @@ otError Leader::RlocLookup(uint16_t aRloc16, bool & aStable, uint8_t *aTlvs, uint8_t aTlvsLength, - bool aExactMatch) + bool aExactMatch, + bool aAllowOtherEntries) { otError error = OT_ERROR_NONE; NetworkDataTlv * cur = reinterpret_cast(aTlvs); @@ -494,6 +495,10 @@ otError Leader::RlocLookup(uint16_t aRloc16, aStable = true; } } + else + { + VerifyOrExit(aAllowOtherEntries, error = OT_ERROR_FAILED); + } } break; @@ -515,6 +520,10 @@ otError Leader::RlocLookup(uint16_t aRloc16, aStable = true; } } + else + { + VerifyOrExit(aAllowOtherEntries, error = OT_ERROR_FAILED); + } } break; @@ -523,7 +532,7 @@ otError Leader::RlocLookup(uint16_t aRloc16, break; } - if (aIn && aStable) + if (aIn && aStable && aAllowOtherEntries) { ExitNow(); } @@ -565,6 +574,10 @@ otError Leader::RlocLookup(uint16_t aRloc16, aStable = true; } } + else + { + VerifyOrExit(aAllowOtherEntries, error = OT_ERROR_FAILED); + } break; @@ -572,7 +585,7 @@ otError Leader::RlocLookup(uint16_t aRloc16, break; } - if (aIn && aStable) + if (aIn && aStable && aAllowOtherEntries) { ExitNow(); } @@ -740,10 +753,14 @@ otError Leader::RegisterNetworkData(uint16_t aRloc16, uint8_t *aTlvs, uint8_t aT bool rlocIn = false; bool rlocStable = false; bool stableUpdated = false; + bool unused; uint8_t oldTlvs[NetworkData::kMaxSize]; uint8_t oldTlvsLength = NetworkData::kMaxSize; - RlocLookup(aRloc16, rlocIn, rlocStable, mTlvs, mLength, true); + // Verify that `aTlvs` only contains entries matching `aRloc16`. + SuccessOrExit(error = RlocLookup(aRloc16, rlocIn, rlocStable, aTlvs, aTlvsLength, true, false)); + + RlocLookup(aRloc16, rlocIn, unused, mTlvs, mLength, true); if (rlocIn) { @@ -767,8 +784,6 @@ otError Leader::RegisterNetworkData(uint16_t aRloc16, uint8_t *aTlvs, uint8_t aT } else { - SuccessOrExit(error = RlocLookup(aRloc16, rlocIn, rlocStable, aTlvs, aTlvsLength, true)); - // No old data to be preserved, lets avoid memcpy() & FindService calls. SuccessOrExit(error = AddNetworkData(aTlvs, aTlvsLength, oldTlvs, 0)); diff --git a/src/core/thread/network_data_leader_ftd.hpp b/src/core/thread/network_data_leader_ftd.hpp index a30b8cf92..b29e01803 100644 --- a/src/core/thread/network_data_leader_ftd.hpp +++ b/src/core/thread/network_data_leader_ftd.hpp @@ -196,7 +196,8 @@ private: bool & aStable, uint8_t *aTlvs, uint8_t aTlvsLength, - bool aExactMatch); + bool aExactMatch, + bool aAllowOtherEntries = true); bool IsStableUpdated(uint8_t *aTlvs, uint8_t aTlvsLength, uint8_t *aTlvsBase, uint8_t aTlvsBaseLength);