mirror of
https://github.com/espressif/openthread.git
synced 2026-08-01 16:47:47 +00:00
[dso] validate parsed TLV size in ProcessKeepAliveMessage() (#12609)
This commit updates the `Dso::Connection::ProcessKeepAliveMessage()` method to use the `OffsetRange` class for parsing TLVs. This approach robustly validates the size of each parsed TLV against the remaining length of the received message. Utilizing `OffsetRange::Contains()` ensures that the reported TLV size via `GetSize()` does not exceed the available bytes in the message, preventing potential out-of-bounds reads or infinite loops when iterating over subsequent TLVs.
This commit is contained in:
@@ -886,11 +886,13 @@ exit:
|
||||
|
||||
Error Dso::Connection::ProcessKeepAliveMessage(const Dns::Header &aHeader, const Message &aMessage)
|
||||
{
|
||||
Error error = kErrorAbort;
|
||||
uint16_t offset = aMessage.GetOffset();
|
||||
Error error = kErrorAbort;
|
||||
OffsetRange offsetRange;
|
||||
Tlv tlv;
|
||||
KeepAliveTlv keepAliveTlv;
|
||||
|
||||
offsetRange.InitFromMessageOffsetToEnd(aMessage);
|
||||
|
||||
if (aHeader.GetType() == Dns::Header::kTypeResponse)
|
||||
{
|
||||
// A Keep Alive response message is allowed on a client from a sever.
|
||||
@@ -918,23 +920,24 @@ Error Dso::Connection::ProcessKeepAliveMessage(const Dns::Header &aHeader, const
|
||||
|
||||
// Parse and validate the Keep Alive Message
|
||||
|
||||
SuccessOrExit(aMessage.Read(offset, keepAliveTlv));
|
||||
offset += keepAliveTlv.GetSize();
|
||||
SuccessOrExit(aMessage.Read(offsetRange, keepAliveTlv));
|
||||
VerifyOrExit(offsetRange.Contains(keepAliveTlv.GetSize()));
|
||||
offsetRange.AdvanceOffset(keepAliveTlv.GetSize());
|
||||
|
||||
VerifyOrExit((keepAliveTlv.GetType() == KeepAliveTlv::kType) && keepAliveTlv.IsValid());
|
||||
|
||||
// Keep Alive message MUST contain only one Keep Alive TLV.
|
||||
|
||||
while (offset < aMessage.GetLength())
|
||||
while (!offsetRange.IsEmpty())
|
||||
{
|
||||
SuccessOrExit(aMessage.Read(offset, tlv));
|
||||
offset += tlv.GetSize();
|
||||
SuccessOrExit(aMessage.Read(offsetRange, tlv));
|
||||
|
||||
VerifyOrExit(offsetRange.Contains(tlv.GetSize()));
|
||||
offsetRange.AdvanceOffset(tlv.GetSize());
|
||||
|
||||
VerifyOrExit((tlv.GetType() != KeepAliveTlv::kType) && (tlv.GetType() != RetryDelayTlv::kType));
|
||||
}
|
||||
|
||||
VerifyOrExit(offset == aMessage.GetLength());
|
||||
|
||||
if (aHeader.GetType() == Dns::Header::kTypeQuery)
|
||||
{
|
||||
if (IsServer())
|
||||
|
||||
Reference in New Issue
Block a user