From 2c6848df1e719879100247fc15fcdfd830a6db59 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Fri, 28 Apr 2023 15:27:01 -0400 Subject: [PATCH] Set a recursion depth limit for TLV (#26301) * Set a recursion depth limit for TLV * Restyled by clang-format * Restyled by prettier-markdown --------- Co-authored-by: Andrei Litvin Co-authored-by: Restyled.io --- docs/ERROR_CODES.md | 1 + src/lib/core/CHIPError.cpp | 3 +++ src/lib/core/CHIPError.h | 5 ++++- src/lib/core/TLVUtilities.cpp | 13 +++++++++++++ src/lib/core/tests/TestCHIPErrorStr.cpp | 1 + 5 files changed, 22 insertions(+), 1 deletion(-) diff --git a/docs/ERROR_CODES.md b/docs/ERROR_CODES.md index d4fd79ed0466c7..38aa66f59f34d0 100644 --- a/docs/ERROR_CODES.md +++ b/docs/ERROR_CODES.md @@ -21,6 +21,7 @@ This file was **AUTOMATICALLY** generated by | 2 | 0x02 | `CHIP_ERROR_CONNECTION_ABORTED` | | 3 | 0x03 | `CHIP_ERROR_INCORRECT_STATE` | | 4 | 0x04 | `CHIP_ERROR_MESSAGE_TOO_LONG` | +| 5 | 0x05 | `CHIP_ERROR_RECURSION_DEPTH_LIMIT` | | 6 | 0x06 | `CHIP_ERROR_TOO_MANY_UNSOLICITED_MESSAGE_HANDLERS` | | 7 | 0x07 | `CHIP_ERROR_NO_UNSOLICITED_MESSAGE_HANDLER` | | 8 | 0x08 | `CHIP_ERROR_NO_CONNECTION_HANDLER` | diff --git a/src/lib/core/CHIPError.cpp b/src/lib/core/CHIPError.cpp index 53f9b7260f530f..1b25f608b88a15 100644 --- a/src/lib/core/CHIPError.cpp +++ b/src/lib/core/CHIPError.cpp @@ -74,6 +74,9 @@ bool FormatCHIPError(char * buf, uint16_t bufSize, CHIP_ERROR err) case CHIP_ERROR_MESSAGE_TOO_LONG.AsInteger(): desc = "Message too long"; break; + case CHIP_ERROR_RECURSION_DEPTH_LIMIT.AsInteger(): + desc = "Recursion depth limit reached"; + break; case CHIP_ERROR_TOO_MANY_UNSOLICITED_MESSAGE_HANDLERS.AsInteger(): desc = "Too many unsolicited message handlers"; break; diff --git a/src/lib/core/CHIPError.h b/src/lib/core/CHIPError.h index e91229e4b3f799..d4471f1b996f76 100644 --- a/src/lib/core/CHIPError.h +++ b/src/lib/core/CHIPError.h @@ -466,7 +466,10 @@ using CHIP_ERROR = ::chip::ChipError; */ #define CHIP_ERROR_MESSAGE_TOO_LONG CHIP_CORE_ERROR(0x04) -// AVAILABLE: 0x05 +/** + * Recursion depth overflow + */ +#define CHIP_ERROR_RECURSION_DEPTH_LIMIT CHIP_CORE_ERROR(0x05) /** * @def CHIP_ERROR_TOO_MANY_UNSOLICITED_MESSAGE_HANDLERS diff --git a/src/lib/core/TLVUtilities.cpp b/src/lib/core/TLVUtilities.cpp index 443adc6ef79ca5..65a88a36bb18b2 100644 --- a/src/lib/core/TLVUtilities.cpp +++ b/src/lib/core/TLVUtilities.cpp @@ -33,6 +33,14 @@ namespace TLV { namespace Utilities { +namespace { + +// Sets up a limit on recursion depth, to avoid any stack overflows +// on very deep TLV structures. Embedded has limited stack space. +constexpr size_t kMaxRecursionDepth = 10; + +} // namespace + struct FindContext { const Tag & mTag; @@ -63,6 +71,11 @@ static CHIP_ERROR Iterate(TLVReader & aReader, size_t aDepth, IterateHandler aHa { CHIP_ERROR retval = CHIP_NO_ERROR; + if (aDepth >= kMaxRecursionDepth) + { + return CHIP_ERROR_RECURSION_DEPTH_LIMIT; + } + if (aReader.GetType() == kTLVType_NotSpecified) { ReturnErrorOnFailure(aReader.Next()); diff --git a/src/lib/core/tests/TestCHIPErrorStr.cpp b/src/lib/core/tests/TestCHIPErrorStr.cpp index bb7d368b9e63cd..87c0967e385c47 100644 --- a/src/lib/core/tests/TestCHIPErrorStr.cpp +++ b/src/lib/core/tests/TestCHIPErrorStr.cpp @@ -53,6 +53,7 @@ static const CHIP_ERROR kTestElements[] = CHIP_ERROR_CONNECTION_ABORTED, CHIP_ERROR_INCORRECT_STATE, CHIP_ERROR_MESSAGE_TOO_LONG, + CHIP_ERROR_RECURSION_DEPTH_LIMIT, CHIP_ERROR_TOO_MANY_UNSOLICITED_MESSAGE_HANDLERS, CHIP_ERROR_NO_UNSOLICITED_MESSAGE_HANDLER, CHIP_ERROR_NO_CONNECTION_HANDLER,