Verifier for FlexBuffers (#6977)

* Verifier for FlexBuffers

* Verifier improvements & fuzzer
This commit is contained in:
Wouter van Oortmerssen
2021-12-10 14:59:08 -08:00
committed by GitHub
parent 705f27f6ee
commit e367ca32ad
11 changed files with 300 additions and 6 deletions

View File

@@ -510,9 +510,12 @@ int FlatCompiler::Compile(int argc, const char **argv) {
LoadBinarySchema(*parser.get(), filename, contents);
} else if (opts.use_flexbuffers) {
if (opts.lang_to_generate == IDLOptions::kJson) {
parser->flex_root_ = flexbuffers::GetRoot(
reinterpret_cast<const uint8_t *>(contents.c_str()),
contents.size());
auto data = reinterpret_cast<const uint8_t *>(contents.c_str());
auto size = contents.size();
std::vector<bool> reuse_tracker;
if (!flexbuffers::VerifyBuffer(data, size, &reuse_tracker))
Error("flexbuffers file failed to verify: " + filename, false);
parser->flex_root_ = flexbuffers::GetRoot(data, size);
} else {
parser->flex_builder_.Clear();
ParseFile(*parser.get(), filename, contents, include_directories);

View File

@@ -2006,6 +2006,9 @@ class CppGenerator : public BaseGenerator {
// FIXME: file_identifier.
code_ += "{{PRE}}verifier.VerifyNestedFlatBuffer<{{CPP_NAME}}>"
"({{NAME}}(), nullptr)\\";
} else if (field.flexbuffer) {
code_ += "{{PRE}}flexbuffers::VerifyNestedFlexBuffer"
"({{NAME}}(), verifier)\\";
}
break;
}

View File

@@ -265,6 +265,12 @@ struct JsonPrinter {
val = reinterpret_cast<const Struct *>(table)->GetStruct<const void *>(
fd.value.offset);
} else if (fd.flexbuffer && opts.json_nested_flexbuffers) {
// We could verify this FlexBuffer before access, but since this sits
// inside a FlatBuffer that we don't know wether it has been verified or
// not, there is little point making this part safer than the parent..
// The caller should really be verifying the whole.
// If the whole buffer is corrupt, we likely crash before we even get
// here.
auto vec = table->GetPointer<const Vector<uint8_t> *>(fd.value.offset);
auto root = flexbuffers::GetRoot(vec->data(), vec->size());
root.ToString(true, opts.strict_json, text);