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

@@ -1740,6 +1740,7 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
verifier.VerifyVector(testarrayofsortedstruct()) &&
VerifyOffset(verifier, VT_FLEX) &&
verifier.VerifyVector(flex()) &&
flexbuffers::VerifyNestedFlexBuffer(flex(), verifier) &&
VerifyOffset(verifier, VT_TEST5) &&
verifier.VerifyVector(test5()) &&
VerifyOffset(verifier, VT_VECTOR_OF_LONGS) &&

View File

@@ -53,7 +53,7 @@ target_compile_options(
fuzzer_config
INTERFACE
$<$<NOT:$<BOOL:${OSS_FUZZ}>>:
-fsanitize-coverage=edge,trace-cmp
-fsanitize-coverage=trace-cmp
>
$<$<BOOL:${USE_ASAN}>:
-fsanitize=fuzzer,undefined,address
@@ -146,6 +146,9 @@ target_link_libraries(parser_fuzzer PRIVATE flatbuffers_fuzzed)
add_executable(verifier_fuzzer flatbuffers_verifier_fuzzer.cc)
target_link_libraries(verifier_fuzzer PRIVATE flatbuffers_fuzzed)
add_executable(flexverifier_fuzzer flexbuffers_verifier_fuzzer.cc)
target_link_libraries(flexverifier_fuzzer PRIVATE flatbuffers_fuzzed)
add_executable(monster_fuzzer flatbuffers_monster_fuzzer.cc)
target_link_libraries(monster_fuzzer PRIVATE flatbuffers_fuzzed)
add_custom_command(

View File

@@ -0,0 +1,14 @@
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stddef.h>
#include <stdint.h>
#include <string>
#include "flatbuffers/flexbuffers.h"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
std::vector<bool> reuse_tracker;
flexbuffers::VerifyBuffer(data, size, &reuse_tracker);
return 0;
}

View File

@@ -10,10 +10,17 @@ For details about **libFuzzer** see: https://llvm.org/docs/LibFuzzer.html
To build and run these tests LLVM compiler (with clang frontend) and CMake should be installed before.
The fuzzer section include three tests:
The fuzzer section include four tests:
- `verifier_fuzzer` checks stability of deserialization engine for `Monster` schema;
- `parser_fuzzer` checks stability of schema and json parser under various inputs;
- `scalar_parser` focused on validation of the parser while parse numeric scalars in schema and/or json files;
- `flexverifier_fuzzer` checks stability of deserialization engine for FlexBuffers only;
## Build
```sh
cd tests/fuzzer
CC=clang CXX=clang++ cmake . -DCMAKE_BUILD_TYPE=Debug -DUSE_ASAN=ON
```
## Run tests with a specific locale
The grammar of the Flatbuffers library is based on printable-ASCII characters.

View File

@@ -1680,6 +1680,7 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
verifier.VerifyVector(testarrayofsortedstruct()) &&
VerifyOffset(verifier, VT_FLEX) &&
verifier.VerifyVector(flex()) &&
flexbuffers::VerifyNestedFlexBuffer(flex(), verifier) &&
VerifyOffset(verifier, VT_TEST5) &&
verifier.VerifyVector(test5()) &&
VerifyOffset(verifier, VT_VECTOR_OF_LONGS) &&

View File

@@ -3022,6 +3022,10 @@ void FlexBuffersTest() {
#endif
// clang-format on
std::vector<bool> reuse_tracker;
TEST_EQ(flexbuffers::VerifyBuffer(slb.GetBuffer().data(), slb.GetBuffer().size(),
&reuse_tracker), true);
auto map = flexbuffers::GetRoot(slb.GetBuffer()).AsMap();
TEST_EQ(map.size(), 7);
auto vec = map["vec"].AsVector();
@@ -3079,6 +3083,8 @@ void FlexBuffersTest() {
slb.Clear();
auto jsontest = "{ a: [ 123, 456.0 ], b: \"hello\", c: true, d: false }";
TEST_EQ(parser.ParseFlexBuffer(jsontest, nullptr, &slb), true);
TEST_EQ(flexbuffers::VerifyBuffer(slb.GetBuffer().data(), slb.GetBuffer().size(),
&reuse_tracker), true);
auto jroot = flexbuffers::GetRoot(slb.GetBuffer());
auto jmap = jroot.AsMap();
auto jvec = jmap["a"].AsVector();
@@ -3116,6 +3122,8 @@ void FlexBuffersFloatingPointTest() {
"{ a: [1.0, nan, inf, infinity, -inf, +inf, -infinity, 8.0] }";
TEST_EQ(parser.ParseFlexBuffer(jsontest, nullptr, &slb), true);
auto jroot = flexbuffers::GetRoot(slb.GetBuffer());
TEST_EQ(flexbuffers::VerifyBuffer(slb.GetBuffer().data(), slb.GetBuffer().size(),
nullptr), true);
auto jmap = jroot.AsMap();
auto jvec = jmap["a"].AsVector();
TEST_EQ(8, jvec.size());
@@ -3159,6 +3167,9 @@ void FlexBuffersDeprecatedTest() {
// same way, the fix lies on the reading side.
slb.EndVector(start, true, false);
slb.Finish();
// Verify because why not.
TEST_EQ(flexbuffers::VerifyBuffer(slb.GetBuffer().data(), slb.GetBuffer().size(),
nullptr), true);
// So now lets read this data back.
// For existing data, since we have no way of knowing what the actual
// bit-width of the size field of the string is, we are going to ignore this