mirror of
https://github.com/espressif/openthread.git
synced 2026-10-02 13:57:38 +00:00
[ncp-buffer] limit number of segments in a frame (being read) (#2377)
This commit adds code in `NcpFrameBuffer` to check and limit the number of segments in a frame (being read). This is to help detect cases where the underlying buffer may get corrupted.
This commit is contained in:
committed by
Jonathan Hui
parent
7eea5e6d96
commit
a1d6ceef62
@@ -772,6 +772,7 @@ otError NcpFrameBuffer::OutFrameRemove(void)
|
|||||||
uint8_t *bufPtr;
|
uint8_t *bufPtr;
|
||||||
otMessage *message;
|
otMessage *message;
|
||||||
uint16_t header;
|
uint16_t header;
|
||||||
|
uint8_t numSegments;
|
||||||
FrameTag tag;
|
FrameTag tag;
|
||||||
|
|
||||||
VerifyOrExit(!IsEmpty(), error = OT_ERROR_NOT_FOUND);
|
VerifyOrExit(!IsEmpty(), error = OT_ERROR_NOT_FOUND);
|
||||||
@@ -784,6 +785,7 @@ otError NcpFrameBuffer::OutFrameRemove(void)
|
|||||||
// Begin at the start of current frame and move through all segments.
|
// Begin at the start of current frame and move through all segments.
|
||||||
|
|
||||||
bufPtr = mReadFrameStart[mReadDirection];
|
bufPtr = mReadFrameStart[mReadDirection];
|
||||||
|
numSegments = 0;
|
||||||
|
|
||||||
while (bufPtr != mWriteFrameStart[mReadDirection])
|
while (bufPtr != mWriteFrameStart[mReadDirection])
|
||||||
{
|
{
|
||||||
@@ -812,6 +814,12 @@ otError NcpFrameBuffer::OutFrameRemove(void)
|
|||||||
|
|
||||||
// Move the pointer to next segment.
|
// Move the pointer to next segment.
|
||||||
bufPtr = GetUpdatedBufPtr(bufPtr, kSegmentHeaderSize + (header & kSegmentHeaderLengthMask), mReadDirection);
|
bufPtr = GetUpdatedBufPtr(bufPtr, kSegmentHeaderSize + (header & kSegmentHeaderLengthMask), mReadDirection);
|
||||||
|
|
||||||
|
numSegments++;
|
||||||
|
|
||||||
|
// If this assert fails, it is a likely indicator that the internal structure of the NCP buffer has been
|
||||||
|
// corrupted.
|
||||||
|
assert(numSegments <= kMaxSegments);
|
||||||
}
|
}
|
||||||
|
|
||||||
mReadFrameStart[mReadDirection] = bufPtr;
|
mReadFrameStart[mReadDirection] = bufPtr;
|
||||||
@@ -858,6 +866,7 @@ uint16_t NcpFrameBuffer::OutFrameGetLength(void)
|
|||||||
uint16_t frameLength = 0;
|
uint16_t frameLength = 0;
|
||||||
uint16_t header;
|
uint16_t header;
|
||||||
uint8_t *bufPtr;
|
uint8_t *bufPtr;
|
||||||
|
uint8_t numSegments;
|
||||||
otMessage *message = NULL;
|
otMessage *message = NULL;
|
||||||
|
|
||||||
// If the frame length was calculated before, return the previously calculated length.
|
// If the frame length was calculated before, return the previously calculated length.
|
||||||
@@ -870,6 +879,7 @@ uint16_t NcpFrameBuffer::OutFrameGetLength(void)
|
|||||||
// Calculate frame length by adding length of all segments and messages within the current frame.
|
// Calculate frame length by adding length of all segments and messages within the current frame.
|
||||||
|
|
||||||
bufPtr = mReadFrameStart[mReadDirection];
|
bufPtr = mReadFrameStart[mReadDirection];
|
||||||
|
numSegments = 0;
|
||||||
|
|
||||||
while (bufPtr != mWriteFrameStart[mReadDirection])
|
while (bufPtr != mWriteFrameStart[mReadDirection])
|
||||||
{
|
{
|
||||||
@@ -904,6 +914,12 @@ uint16_t NcpFrameBuffer::OutFrameGetLength(void)
|
|||||||
|
|
||||||
// Move the pointer to next segment.
|
// Move the pointer to next segment.
|
||||||
bufPtr = GetUpdatedBufPtr(bufPtr, kSegmentHeaderSize + (header & kSegmentHeaderLengthMask), mReadDirection);
|
bufPtr = GetUpdatedBufPtr(bufPtr, kSegmentHeaderSize + (header & kSegmentHeaderLengthMask), mReadDirection);
|
||||||
|
|
||||||
|
numSegments++;
|
||||||
|
|
||||||
|
// If this assert fails, it is a likely indicator that the internal structure of the NCP buffer has been
|
||||||
|
// corrupted.
|
||||||
|
assert(numSegments <= kMaxSegments);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remember the calculated frame length for current active frame.
|
// Remember the calculated frame length for current active frame.
|
||||||
|
|||||||
@@ -571,6 +571,7 @@ private:
|
|||||||
kUnknownFrameLength = 0xffff, // Value used when frame length is unknown.
|
kUnknownFrameLength = 0xffff, // Value used when frame length is unknown.
|
||||||
kSegmentHeaderSize = 2, // Length of the segment header.
|
kSegmentHeaderSize = 2, // Length of the segment header.
|
||||||
kSegmentHeaderLengthMask = 0x3fff, // Bit mask to get the length from the segment header
|
kSegmentHeaderLengthMask = 0x3fff, // Bit mask to get the length from the segment header
|
||||||
|
kMaxSegments = 10, // Max number of segments allowed in a frame
|
||||||
|
|
||||||
kSegmentHeaderNoFlag = 0, // No flags are set.
|
kSegmentHeaderNoFlag = 0, // No flags are set.
|
||||||
kSegmentHeaderNewFrameFlag = (1 << 15), // Indicates that this segment starts a new frame.
|
kSegmentHeaderNewFrameFlag = (1 << 15), // Indicates that this segment starts a new frame.
|
||||||
|
|||||||
Reference in New Issue
Block a user