Skip to content

Commit ff121bf

Browse files
authored
[spinel] fix out-of-bounds read in GetNextSavedFrame when RCP recover (openthread#13189)
1 parent 4394c09 commit ff121bf

1 file changed

Lines changed: 17 additions & 0 deletions

File tree

src/lib/spinel/multi_frame_buffer.hpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040

4141
#include <openthread/error.h>
4242

43+
#include "common/code_utils.hpp"
4344
#include "lib/utils/endian.hpp"
4445

4546
namespace ot {
@@ -179,6 +180,7 @@ template <uint16_t kSize> class MultiFrameBuffer : public FrameWritePointer
179180
*/
180181
MultiFrameBuffer(void)
181182
: FrameWritePointer()
183+
, mBufferCleared(true)
182184
{
183185
Clear();
184186
}
@@ -193,6 +195,7 @@ template <uint16_t kSize> class MultiFrameBuffer : public FrameWritePointer
193195
mWriteFrameStart = mBuffer;
194196
mWritePointer = mBuffer + kHeaderSize;
195197
mRemainingLength = kSize - kHeaderSize;
198+
mBufferCleared = true;
196199

197200
IgnoreError(SetSkipLength(0));
198201
}
@@ -348,6 +351,17 @@ template <uint16_t kSize> class MultiFrameBuffer : public FrameWritePointer
348351

349352
assert(aFrame == nullptr || (mBuffer <= aFrame && aFrame < GetArrayEnd(mBuffer)));
350353

354+
if (aFrame == nullptr)
355+
{
356+
mBufferCleared = false;
357+
}
358+
else if (mBufferCleared)
359+
{
360+
aLength = 0;
361+
aFrame = nullptr;
362+
ExitNow(error = OT_ERROR_NOT_FOUND);
363+
}
364+
351365
aFrame = (aFrame == nullptr) ? mBuffer : aFrame + aLength;
352366

353367
if (HasSavedFrame() && (aFrame != mWriteFrameStart))
@@ -365,6 +379,7 @@ template <uint16_t kSize> class MultiFrameBuffer : public FrameWritePointer
365379
error = OT_ERROR_NOT_FOUND;
366380
}
367381

382+
exit:
368383
return error;
369384
}
370385

@@ -385,6 +400,7 @@ template <uint16_t kSize> class MultiFrameBuffer : public FrameWritePointer
385400
mWritePointer -= len;
386401
mWriteFrameStart -= len;
387402
mRemainingLength += len;
403+
mBufferCleared = true;
388404
}
389405
}
390406

@@ -443,6 +459,7 @@ template <uint16_t kSize> class MultiFrameBuffer : public FrameWritePointer
443459

444460
uint8_t mBuffer[kSize];
445461
uint8_t *mWriteFrameStart; // Pointer to start of current frame being written.
462+
bool mBufferCleared; // Tracks if buffer was cleared during an active iteration.
446463
};
447464

448465
} // namespace Spinel

0 commit comments

Comments
 (0)