From 0cc913b6b5f90824f0a36e5ff387fa6fff942ada Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Wed, 23 Jan 2019 10:16:48 -0800 Subject: [PATCH] [network-data] add length checks to insert operations (#3495) --- src/core/thread/network_data_local.cpp | 30 ++++++++++++++++++-------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/core/thread/network_data_local.cpp b/src/core/thread/network_data_local.cpp index fa0c90efb..65b85a23e 100644 --- a/src/core/thread/network_data_local.cpp +++ b/src/core/thread/network_data_local.cpp @@ -53,19 +53,23 @@ Local::Local(Instance &aInstance) otError Local::AddOnMeshPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength, int8_t aPrf, uint8_t aFlags, bool aStable) { - otError error = OT_ERROR_NONE; + otError error = OT_ERROR_NONE; + uint8_t prefixLengthBytes = BitVectorBytes(aPrefixLength); + uint8_t appendLength; PrefixTlv * prefixTlv; BorderRouterTlv *brTlv; - VerifyOrExit(Ip6::Address::PrefixMatch(aPrefix, GetNetif().GetMle().GetMeshLocalPrefix().m8, - (aPrefixLength + 7) / 8) < Ip6::Address::kMeshLocalPrefixLength, + VerifyOrExit(Ip6::Address::PrefixMatch(aPrefix, GetNetif().GetMle().GetMeshLocalPrefix().m8, prefixLengthBytes) < + Ip6::Address::kMeshLocalPrefixLength, error = OT_ERROR_INVALID_ARGS); RemoveOnMeshPrefix(aPrefix, aPrefixLength); + appendLength = sizeof(PrefixTlv) + prefixLengthBytes + sizeof(BorderRouterTlv) + sizeof(BorderRouterEntry); + VerifyOrExit(mLength + appendLength <= sizeof(mTlvs), error = OT_ERROR_NO_BUFS); + prefixTlv = reinterpret_cast(mTlvs + mLength); - Insert(reinterpret_cast(prefixTlv), - sizeof(PrefixTlv) + BitVectorBytes(aPrefixLength) + sizeof(BorderRouterTlv) + sizeof(BorderRouterEntry)); + Insert(reinterpret_cast(prefixTlv), appendLength); prefixTlv->Init(0, aPrefixLength, aPrefix); prefixTlv->SetSubTlvsLength(sizeof(BorderRouterTlv) + sizeof(BorderRouterEntry)); @@ -107,14 +111,18 @@ exit: otError Local::AddHasRoutePrefix(const uint8_t *aPrefix, uint8_t aPrefixLength, int8_t aPrf, bool aStable) { + otError error = OT_ERROR_NONE; PrefixTlv * prefixTlv; HasRouteTlv *hasRouteTlv; + uint8_t appendLength; RemoveHasRoutePrefix(aPrefix, aPrefixLength); + appendLength = sizeof(PrefixTlv) + BitVectorBytes(aPrefixLength) + sizeof(HasRouteTlv) + sizeof(HasRouteEntry); + VerifyOrExit(mLength + appendLength <= sizeof(mTlvs), error = OT_ERROR_NO_BUFS); + prefixTlv = reinterpret_cast(mTlvs + mLength); - Insert(reinterpret_cast(prefixTlv), - sizeof(PrefixTlv) + BitVectorBytes(aPrefixLength) + sizeof(HasRouteTlv) + sizeof(HasRouteEntry)); + Insert(reinterpret_cast(prefixTlv), appendLength); prefixTlv->Init(0, aPrefixLength, aPrefix); prefixTlv->SetSubTlvsLength(sizeof(HasRouteTlv) + sizeof(HasRouteEntry)); @@ -133,7 +141,9 @@ otError Local::AddHasRoutePrefix(const uint8_t *aPrefix, uint8_t aPrefixLength, ClearResubmitDelayTimer(); otDumpDebgNetData("add route done", mTlvs, mLength); - return OT_ERROR_NONE; + +exit: + return error; } otError Local::RemoveHasRoutePrefix(const uint8_t *aPrefix, uint8_t aPrefixLength) @@ -168,6 +178,8 @@ otError Local::AddService(uint32_t aEnterpriseNumber, RemoveService(aEnterpriseNumber, aServiceData, aServiceDataLength); + VerifyOrExit(mLength + sizeof(NetworkDataTlv) + serviceTlvLength <= sizeof(mTlvs), error = OT_ERROR_NO_BUFS); + serviceTlv = reinterpret_cast(mTlvs + mLength); Insert(reinterpret_cast(serviceTlv), serviceTlvLength + sizeof(NetworkDataTlv)); @@ -196,7 +208,7 @@ otError Local::AddService(uint32_t aEnterpriseNumber, otDumpDebgNetData("add service done", mTlvs, mLength); - // exit: +exit: return error; }