mirror of
https://github.com/espressif/openthread.git
synced 2026-09-14 13:10:08 +00:00
[mac] validate Header IE content length before reading IE structs (#13184)
GetThreadIe(), GetCslIe(), and GetTimeIe() read a fixed content struct (VendorIeHeader / CslIe / TimeIe) at `ie + sizeof(HeaderIe)` after matching the IE id, without first checking that the IE's Length field covers that struct. FindPayloadIndex() only guarantees the IE header plus its declared Length fit within the frame, so a matching IE whose Length is shorter than the content struct (e.g. a zero-length vendor IE placed at the end of the header-IE region) causes a read past the IE content, and past the PSDU buffer when the IE ends at the frame boundary. Gate each content read on the IE Length being at least the corresponding kIeContentSize before dereferencing the struct.
This commit is contained in:
@@ -1196,7 +1196,7 @@ const uint8_t *Frame::GetThreadIe(uint8_t aSubType) const
|
||||
{
|
||||
const HeaderIe *ie = reinterpret_cast<const HeaderIe *>(&mPsdu[index]);
|
||||
|
||||
if (ie->GetId() == VendorIeHeader::kHeaderIeId)
|
||||
if ((ie->GetId() == VendorIeHeader::kHeaderIeId) && (ie->GetLength() >= VendorIeHeader::kIeContentSize))
|
||||
{
|
||||
const VendorIeHeader *vendorIe =
|
||||
reinterpret_cast<const VendorIeHeader *>(reinterpret_cast<const uint8_t *>(ie) + sizeof(HeaderIe));
|
||||
@@ -1242,6 +1242,7 @@ const CslIe *Frame::GetCslIe(void) const
|
||||
|
||||
cur = GetHeaderIe(CslIe::kHeaderIeId);
|
||||
VerifyOrExit(cur != nullptr);
|
||||
VerifyOrExit(reinterpret_cast<const HeaderIe *>(cur)->GetLength() >= CslIe::kIeContentSize);
|
||||
csl = reinterpret_cast<const CslIe *>(cur + sizeof(HeaderIe));
|
||||
|
||||
exit:
|
||||
@@ -1270,6 +1271,7 @@ const TimeIe *Frame::GetTimeIe(void) const
|
||||
|
||||
cur = GetHeaderIe(VendorIeHeader::kHeaderIeId);
|
||||
VerifyOrExit(cur != nullptr);
|
||||
VerifyOrExit(reinterpret_cast<const HeaderIe *>(cur)->GetLength() >= TimeIe::kIeContentSize);
|
||||
|
||||
cur += sizeof(HeaderIe);
|
||||
|
||||
|
||||
@@ -211,7 +211,10 @@ public:
|
||||
{
|
||||
const uint8_t *ie = GetHeaderIe(RendezvousTimeIe::kHeaderIeId);
|
||||
|
||||
return (ie != nullptr) ? reinterpret_cast<const RendezvousTimeIe *>(ie + sizeof(HeaderIe)) : nullptr;
|
||||
return (ie != nullptr &&
|
||||
reinterpret_cast<const HeaderIe *>(ie)->GetLength() >= RendezvousTimeIe::kIeContentSize)
|
||||
? reinterpret_cast<const RendezvousTimeIe *>(ie + sizeof(HeaderIe))
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -230,7 +233,9 @@ public:
|
||||
{
|
||||
const uint8_t *ie = GetThreadIe(ConnectionIe::kThreadIeSubtype);
|
||||
|
||||
return (ie != nullptr) ? reinterpret_cast<const ConnectionIe *>(ie + sizeof(HeaderIe)) : nullptr;
|
||||
return (ie != nullptr && reinterpret_cast<const HeaderIe *>(ie)->GetLength() >= ConnectionIe::kIeContentSize)
|
||||
? reinterpret_cast<const ConnectionIe *>(ie + sizeof(HeaderIe))
|
||||
: nullptr;
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE || OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||
|
||||
|
||||
Reference in New Issue
Block a user