C++ verifier now primarily uses offsets instead of pointers.

Fix for: https://bugs.chromium.org/p/chromium/issues/detail?id=834710

Before, the verifier would create pointers to objects, and then
verify they are inside the buffer. But since even constructing pointers
that are outside a valid allocation is Undefinied Behavior in C++, this
can trigger UBSAN (with -fsanitize=pointer-overflow).

Now instead the bounds checking is first performed using offsets
before pointers are even created.

Change-Id: If4d376e90df9847e543247e70a062671914dae1b
Tested: on Linux.
This commit is contained in:
Wouter van Oortmerssen
2018-07-12 16:26:17 -07:00
parent cda1525f84
commit 8f1bebba05
2 changed files with 75 additions and 47 deletions

View File

@@ -496,7 +496,7 @@ bool VerifyStruct(flatbuffers::Verifier &v,
if (required && !offset) { return false; }
return !offset ||
v.Verify(reinterpret_cast<const uint8_t *>(&parent_table) + offset,
v.Verify(reinterpret_cast<const uint8_t *>(&parent_table), offset,
obj.bytesize());
}
@@ -505,10 +505,9 @@ bool VerifyVectorOfStructs(flatbuffers::Verifier &v,
voffset_t field_offset,
const reflection::Object &obj, bool required) {
auto p = parent_table.GetPointer<const uint8_t *>(field_offset);
const uint8_t *end;
if (required && !p) { return false; }
return !p || v.VerifyVector(p, obj.bytesize(), &end);
return !p || v.VerifyVector(p, obj.bytesize());
}
// forward declare to resolve cyclic deps between VerifyObject and VerifyVector