mirror of
https://github.com/espressif/openthread.git
synced 2026-08-26 20:19:53 +00:00
[mac] fix infinite loop in GetHeaderIe() and GetThreadIe() (#12598)
This commit addresses a timeout issue reported by a fuzzer when processing MAC frames with malformed Header IEs. Specifically: - In `FindPayloadIndex()`, added validation to ensure the returned index does not exceed `kMaxPsduSize` (254). If the index exceeds this value, it now returns `kInvalidIndex` (255). This prevents callers from experiencing wrap-around issues when they cast the result to `uint8_t`. - In `GetHeaderIe()` and `GetThreadIe()`, changed the `index` and `payloadIndex` variables from `uint8_t` to `uint16_t`. This ensures that any increment during the loop does not wrap around, which was a primary cause of the infinite loop. - Updated the loop condition from `index <= payloadIndex` to `index < payloadIndex`. Since `payloadIndex` points to the start of the payload (the byte after the last Header IE), a strict less-than comparison is correct and prevents the loop from attempting to parse the payload itself as a Header IE. These changes ensure robust parsing of IEEE 802.15.4 frames, even when they contain unexpected or malformed Information Elements.
This commit is contained in:
@@ -1121,7 +1121,7 @@ uint8_t Frame::FindPayloadIndex(void) const
|
||||
}
|
||||
|
||||
exit:
|
||||
return static_cast<uint8_t>(index);
|
||||
return (index <= kMaxPsduSize) ? static_cast<uint8_t>(index) : kInvalidIndex;
|
||||
}
|
||||
|
||||
const uint8_t *Frame::GetPayload(void) const
|
||||
@@ -1153,8 +1153,8 @@ exit:
|
||||
|
||||
const uint8_t *Frame::GetHeaderIe(uint8_t aIeId) const
|
||||
{
|
||||
uint8_t index = FindHeaderIeIndex();
|
||||
uint8_t payloadIndex = FindPayloadIndex();
|
||||
uint16_t index = FindHeaderIeIndex();
|
||||
uint16_t payloadIndex = FindPayloadIndex();
|
||||
const uint8_t *header = nullptr;
|
||||
|
||||
// `FindPayloadIndex()` verifies that Header IE(s) in frame (if present)
|
||||
@@ -1162,7 +1162,7 @@ const uint8_t *Frame::GetHeaderIe(uint8_t aIeId) const
|
||||
|
||||
VerifyOrExit((index != kInvalidIndex) && (payloadIndex != kInvalidIndex));
|
||||
|
||||
while (index <= payloadIndex)
|
||||
while (index < payloadIndex)
|
||||
{
|
||||
const HeaderIe *ie = reinterpret_cast<const HeaderIe *>(&mPsdu[index]);
|
||||
|
||||
@@ -1183,15 +1183,15 @@ exit:
|
||||
OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE || OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
|
||||
const uint8_t *Frame::GetThreadIe(uint8_t aSubType) const
|
||||
{
|
||||
uint8_t index = FindHeaderIeIndex();
|
||||
uint8_t payloadIndex = FindPayloadIndex();
|
||||
uint16_t index = FindHeaderIeIndex();
|
||||
uint16_t payloadIndex = FindPayloadIndex();
|
||||
const uint8_t *header = nullptr;
|
||||
|
||||
// `FindPayloadIndex()` verifies that Header IE(s) in frame (if present)
|
||||
// are well-formed.
|
||||
VerifyOrExit((index != kInvalidIndex) && (payloadIndex != kInvalidIndex));
|
||||
|
||||
while (index <= payloadIndex)
|
||||
while (index < payloadIndex)
|
||||
{
|
||||
const HeaderIe *ie = reinterpret_cast<const HeaderIe *>(&mPsdu[index]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user