mirror of
https://github.com/espressif/openthread.git
synced 2026-08-01 16:47:47 +00:00
[mle] reject ChildIdResponse if included dataset TLV is ill-formed (#7599)
This commit contains the following changes: - The `Dataset` method which reads the dataset TLVs from a message is renamed to `ReadFromMessage()` and after reading the TLVs, it also checks that the TLVs in the Dataset are valid (well-formed). - The `Active/PendingDataset::Save()` methods are updated to return error in the case the parsed dataset is not well-formed. - The `Mle::HandleChildIdRequest()` rejects the response if the included dataset is not well-formed. This ensures that device stays detached if it cannot accept and save the dataset it gets from the parent candidate.
This commit is contained in:
@@ -435,13 +435,15 @@ Error Dataset::SetTlv(const Tlv &aTlv)
|
||||
return SetTlv(aTlv.GetType(), aTlv.GetValue(), aTlv.GetLength());
|
||||
}
|
||||
|
||||
Error Dataset::Set(const Message &aMessage, uint16_t aOffset, uint8_t aLength)
|
||||
Error Dataset::ReadFromMessage(const Message &aMessage, uint16_t aOffset, uint8_t aLength)
|
||||
{
|
||||
Error error = kErrorInvalidArgs;
|
||||
Error error = kErrorParse;
|
||||
|
||||
SuccessOrExit(aMessage.Read(aOffset, mTlvs, aLength));
|
||||
mLength = aLength;
|
||||
|
||||
VerifyOrExit(IsValid(), error = kErrorParse);
|
||||
|
||||
mUpdateTime = TimerMilli::GetNow();
|
||||
error = kErrorNone;
|
||||
|
||||
|
||||
@@ -782,17 +782,17 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the Dataset using TLVs stored in a message buffer.
|
||||
* This method reads the Dataset from a given message and checks that it is well-formed and valid.
|
||||
*
|
||||
* @param[in] aMessage The message buffer.
|
||||
* @param[in] aOffset The message buffer offset where the dataset starts.
|
||||
* @param[in] aLength The TLVs length in the message buffer in bytes.
|
||||
* @param[in] aMessage The message to read from.
|
||||
* @param[in] aOffset The offset in @p aMessage to start reading the Dataset TLVs.
|
||||
* @param[in] aLength The dataset length in bytes.
|
||||
*
|
||||
* @retval kErrorNone Successfully set the Dataset.
|
||||
* @retval kErrorInvalidArgs The values of @p aOffset and @p aLength are not valid for @p aMessage.
|
||||
* @retval kErrorNone Successfully read and validated the Dataset.
|
||||
* @retval kErrorParse Could not read or parse the dataset from @p aMessage.
|
||||
*
|
||||
*/
|
||||
Error Set(const Message &aMessage, uint16_t aOffset, uint8_t aLength);
|
||||
Error ReadFromMessage(const Message &aMessage, uint16_t aOffset, uint8_t aLength);
|
||||
|
||||
/**
|
||||
* This method sets the Dataset using an existing Dataset.
|
||||
|
||||
@@ -140,7 +140,7 @@ Error DatasetManager::Save(const Dataset &aDataset)
|
||||
|
||||
if (isNetworkkeyUpdated || compare > 0)
|
||||
{
|
||||
IgnoreError(mLocal.Save(aDataset));
|
||||
SuccessOrExit(error = mLocal.Save(aDataset));
|
||||
|
||||
#if OPENTHREAD_FTD
|
||||
Get<NetworkData::Leader>().IncrementVersionAndStableVersion();
|
||||
@@ -690,9 +690,9 @@ Error ActiveDataset::Save(const Timestamp &aTimestamp, const Message &aMessage,
|
||||
Error error = kErrorNone;
|
||||
Dataset dataset;
|
||||
|
||||
SuccessOrExit(error = dataset.Set(aMessage, aOffset, aLength));
|
||||
SuccessOrExit(error = dataset.ReadFromMessage(aMessage, aOffset, aLength));
|
||||
dataset.SetTimestamp(Dataset::kActive, aTimestamp);
|
||||
IgnoreError(DatasetManager::Save(dataset));
|
||||
error = DatasetManager::Save(dataset);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
@@ -777,9 +777,9 @@ Error PendingDataset::Save(const Timestamp &aTimestamp, const Message &aMessage,
|
||||
Error error = kErrorNone;
|
||||
Dataset dataset;
|
||||
|
||||
SuccessOrExit(error = dataset.Set(aMessage, aOffset, aLength));
|
||||
SuccessOrExit(error = dataset.ReadFromMessage(aMessage, aOffset, aLength));
|
||||
dataset.SetTimestamp(Dataset::kPending, aTimestamp);
|
||||
IgnoreError(DatasetManager::Save(dataset));
|
||||
SuccessOrExit(error = DatasetManager::Save(dataset));
|
||||
StartDelayTimer();
|
||||
|
||||
exit:
|
||||
|
||||
@@ -272,6 +272,9 @@ protected:
|
||||
* @param[in] aOffset The offset where the Operational Dataset begins.
|
||||
* @param[in] aLength The length of the Operational Dataset.
|
||||
*
|
||||
* @retval kErrorNone Successfully parsed the Dataset from the @p aMessage and saved it.
|
||||
* @retval kErrorParse Could not parse the Dataset from @p aMessage.
|
||||
*
|
||||
*/
|
||||
Error Save(const Timestamp &aTimestamp, const Message &aMessage, uint16_t aOffset, uint8_t aLength);
|
||||
|
||||
@@ -419,6 +422,9 @@ public:
|
||||
* @param[in] aOffset The offset where the Operational Dataset begins.
|
||||
* @param[in] aLength The length of the Operational Dataset.
|
||||
*
|
||||
* @retval kErrorNone Successfully parsed the Dataset from the @p aMessage and saved it.
|
||||
* @retval kErrorParse Could not parse the Dataset from @p aMessage.
|
||||
*
|
||||
*/
|
||||
Error Save(const Timestamp &aTimestamp, const Message &aMessage, uint16_t aOffset, uint8_t aLength);
|
||||
|
||||
|
||||
@@ -3696,7 +3696,8 @@ void Mle::HandleChildIdResponse(const Message & aMessage,
|
||||
if (Tlv::FindTlvOffset(aMessage, Tlv::kActiveDataset, offset) == kErrorNone)
|
||||
{
|
||||
IgnoreError(aMessage.Read(offset, tlv));
|
||||
IgnoreError(Get<MeshCoP::ActiveDataset>().Save(timestamp, aMessage, offset + sizeof(tlv), tlv.GetLength()));
|
||||
SuccessOrExit(
|
||||
error = Get<MeshCoP::ActiveDataset>().Save(timestamp, aMessage, offset + sizeof(tlv), tlv.GetLength()));
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user