Check dictionary sizes to avoid any heap overflows
Tested:
Unit tested
Signed-off-by: Kasun Athukorala <kasunath@google.com>
Change-Id: I34972b7f4daf0e818461ef2a4842966a247fc20e
diff --git a/test/bej_decoder_test.cpp b/test/bej_decoder_test.cpp
index cf76d2b..f881c3e 100644
--- a/test/bej_decoder_test.cpp
+++ b/test/bej_decoder_test.cpp
@@ -66,8 +66,11 @@
BejDictionaries dictionaries = {
.schemaDictionary = inputsOrErr->schemaDictionary,
+ .schemaDictionarySize = inputsOrErr->schemaDictionarySize,
.annotationDictionary = inputsOrErr->annotationDictionary,
+ .annotationDictionarySize = inputsOrErr->annotationDictionarySize,
.errorDictionary = inputsOrErr->errorDictionary,
+ .errorDictionarySize = inputsOrErr->errorDictionarySize,
};
BejDecoderJson decoder;
@@ -108,8 +111,11 @@
BejDictionaries dictionaries = {
.schemaDictionary = inputsOrErr->schemaDictionary,
+ .schemaDictionarySize = inputsOrErr->schemaDictionarySize,
.annotationDictionary = inputsOrErr->annotationDictionary,
+ .annotationDictionarySize = inputsOrErr->annotationDictionarySize,
.errorDictionary = inputsOrErr->errorDictionary,
+ .errorDictionarySize = inputsOrErr->errorDictionarySize,
};
// Each array element below consists of a set and two properties, resulting
@@ -167,8 +173,11 @@
BejDictionaries dictionaries = {
.schemaDictionary = inputsOrErr->schemaDictionary,
+ .schemaDictionarySize = inputsOrErr->schemaDictionarySize,
.annotationDictionary = inputsOrErr->annotationDictionary,
+ .annotationDictionarySize = inputsOrErr->annotationDictionarySize,
.errorDictionary = inputsOrErr->errorDictionary,
+ .errorDictionarySize = inputsOrErr->errorDictionarySize,
};
auto root = std::make_unique<RedfishPropertyParent>();
@@ -228,8 +237,11 @@
BejDictionaries dictionaries = {
.schemaDictionary = inputsOrErr->schemaDictionary,
+ .schemaDictionarySize = inputsOrErr->schemaDictionarySize,
.annotationDictionary = inputsOrErr->annotationDictionary,
+ .annotationDictionarySize = inputsOrErr->annotationDictionarySize,
.errorDictionary = inputsOrErr->errorDictionary,
+ .errorDictionarySize = inputsOrErr->errorDictionarySize,
};
auto root = std::make_unique<RedfishPropertyParent>();
@@ -258,8 +270,11 @@
BejDictionaries dictionaries = {
.schemaDictionary = inputsOrErr->schemaDictionary,
+ .schemaDictionarySize = inputsOrErr->schemaDictionarySize,
.annotationDictionary = inputsOrErr->annotationDictionary,
+ .annotationDictionarySize = inputsOrErr->annotationDictionarySize,
.errorDictionary = inputsOrErr->errorDictionary,
+ .errorDictionarySize = inputsOrErr->errorDictionarySize,
};
auto root = std::make_unique<RedfishPropertyParent>();
@@ -282,4 +297,61 @@
bejErrorInvalidSize);
}
+TEST(BejDecoderSecurityTest, InvalidSchemaDictionarySize)
+{
+ auto inputsOrErr = loadInputs(dummySimpleTestFiles);
+ ASSERT_TRUE(inputsOrErr);
+
+ BejDictionaries dictionaries = {
+ .schemaDictionary = inputsOrErr->schemaDictionary,
+ .schemaDictionarySize = 10,
+ .annotationDictionary = inputsOrErr->annotationDictionary,
+ .annotationDictionarySize = inputsOrErr->annotationDictionarySize,
+ .errorDictionary = inputsOrErr->errorDictionary,
+ .errorDictionarySize = inputsOrErr->errorDictionarySize,
+ };
+
+ BejDecoderJson decoder;
+ EXPECT_THAT(decoder.decode(dictionaries, inputsOrErr->encodedStream),
+ bejErrorInvalidSize);
+}
+
+TEST(BejDecoderSecurityTest, InvalidAnnotationDictionarySize)
+{
+ auto inputsOrErr = loadInputs(dummySimpleTestFiles);
+ ASSERT_TRUE(inputsOrErr);
+
+ BejDictionaries dictionaries = {
+ .schemaDictionary = inputsOrErr->schemaDictionary,
+ .schemaDictionarySize = inputsOrErr->schemaDictionarySize,
+ .annotationDictionary = inputsOrErr->annotationDictionary,
+ .annotationDictionarySize = 10,
+ .errorDictionary = inputsOrErr->errorDictionary,
+ .errorDictionarySize = inputsOrErr->errorDictionarySize,
+ };
+
+ BejDecoderJson decoder;
+ EXPECT_THAT(decoder.decode(dictionaries, inputsOrErr->encodedStream),
+ bejErrorInvalidSize);
+}
+
+TEST(BejDecoderSecurityTest, InvalidErrorDictionarySize)
+{
+ auto inputsOrErr = loadInputs(dummySimpleTestFiles);
+ ASSERT_TRUE(inputsOrErr);
+
+ BejDictionaries dictionaries = {
+ .schemaDictionary = inputsOrErr->schemaDictionary,
+ .schemaDictionarySize = inputsOrErr->schemaDictionarySize,
+ .annotationDictionary = inputsOrErr->annotationDictionary,
+ .annotationDictionarySize = inputsOrErr->annotationDictionarySize,
+ .errorDictionary = inputsOrErr->errorDictionary,
+ .errorDictionarySize = 10,
+ };
+
+ BejDecoderJson decoder;
+ EXPECT_THAT(decoder.decode(dictionaries, inputsOrErr->encodedStream),
+ bejErrorInvalidSize);
+}
+
} // namespace libbej
diff --git a/test/bej_encoder_test.cpp b/test/bej_encoder_test.cpp
index 413d4e1..113a9de 100644
--- a/test/bej_encoder_test.cpp
+++ b/test/bej_encoder_test.cpp
@@ -344,8 +344,11 @@
BejDictionaries dictionaries = {
.schemaDictionary = inputsOrErr->schemaDictionary,
+ .schemaDictionarySize = inputsOrErr->schemaDictionarySize,
.annotationDictionary = inputsOrErr->annotationDictionary,
+ .annotationDictionarySize = inputsOrErr->annotationDictionarySize,
.errorDictionary = inputsOrErr->errorDictionary,
+ .errorDictionarySize = inputsOrErr->errorDictionarySize,
};
std::vector<uint8_t> outputBuffer;
@@ -388,8 +391,11 @@
BejDictionaries dictionaries = {
.schemaDictionary = inputsOrErr->schemaDictionary,
+ .schemaDictionarySize = inputsOrErr->schemaDictionarySize,
.annotationDictionary = inputsOrErr->annotationDictionary,
+ .annotationDictionarySize = inputsOrErr->annotationDictionarySize,
.errorDictionary = inputsOrErr->errorDictionary,
+ .errorDictionarySize = inputsOrErr->errorDictionarySize,
};
libbej::BejEncoderJson encoder;
diff --git a/test/include/bej_common_test.hpp b/test/include/bej_common_test.hpp
index 74d8c83..9d6165d 100644
--- a/test/include/bej_common_test.hpp
+++ b/test/include/bej_common_test.hpp
@@ -28,8 +28,11 @@
{
nlohmann::json expectedJson;
const uint8_t* schemaDictionary;
+ uint32_t schemaDictionarySize;
const uint8_t* annotationDictionary;
+ uint32_t annotationDictionarySize;
const uint8_t* errorDictionary;
+ uint32_t errorDictionarySize;
std::span<const uint8_t> encodedStream;
};
@@ -65,15 +68,19 @@
jsonInput >> expJson;
static uint8_t schemaDictBuffer[maxBufferSize];
- if (readBinaryFile(files.schemaDictionaryFile,
- std::span(schemaDictBuffer, maxBufferSize)) == 0)
+ uint32_t schemaDictSize = 0;
+ if ((schemaDictSize =
+ readBinaryFile(files.schemaDictionaryFile,
+ std::span(schemaDictBuffer, maxBufferSize))) == 0)
{
return std::nullopt;
}
static uint8_t annoDictBuffer[maxBufferSize];
- if (readBinaryFile(files.annotationDictionaryFile,
- std::span(annoDictBuffer, maxBufferSize)) == 0)
+ uint32_t annoDictSize = 0;
+ if ((annoDictSize =
+ readBinaryFile(files.annotationDictionaryFile,
+ std::span(annoDictBuffer, maxBufferSize))) == 0)
{
return std::nullopt;
}
@@ -87,10 +94,12 @@
}
static uint8_t errorDict[maxBufferSize];
+ uint32_t errorDictSize = 0;
if (readErrorDictionary)
{
- if (readBinaryFile(files.errorDictionaryFile,
- std::span(errorDict, maxBufferSize)) == 0)
+ if ((errorDictSize =
+ readBinaryFile(files.errorDictionaryFile,
+ std::span(errorDict, maxBufferSize))) == 0)
{
return std::nullopt;
}
@@ -99,8 +108,11 @@
BejTestInputs inputs = {
.expectedJson = expJson,
.schemaDictionary = schemaDictBuffer,
+ .schemaDictionarySize = schemaDictSize,
.annotationDictionary = annoDictBuffer,
+ .annotationDictionarySize = annoDictSize,
.errorDictionary = errorDict,
+ .errorDictionarySize = errorDictSize,
.encodedStream = std::span(encBuffer, encLen),
};
return inputs;