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.
parent cda1525f
This diff is collapsed.
...@@ -496,7 +496,7 @@ bool VerifyStruct(flatbuffers::Verifier &v, ...@@ -496,7 +496,7 @@ bool VerifyStruct(flatbuffers::Verifier &v,
if (required && !offset) { return false; } if (required && !offset) { return false; }
return !offset || return !offset ||
v.Verify(reinterpret_cast<const uint8_t *>(&parent_table) + offset, v.Verify(reinterpret_cast<const uint8_t *>(&parent_table), offset,
obj.bytesize()); obj.bytesize());
} }
...@@ -505,10 +505,9 @@ bool VerifyVectorOfStructs(flatbuffers::Verifier &v, ...@@ -505,10 +505,9 @@ bool VerifyVectorOfStructs(flatbuffers::Verifier &v,
voffset_t field_offset, voffset_t field_offset,
const reflection::Object &obj, bool required) { const reflection::Object &obj, bool required) {
auto p = parent_table.GetPointer<const uint8_t *>(field_offset); auto p = parent_table.GetPointer<const uint8_t *>(field_offset);
const uint8_t *end;
if (required && !p) { return false; } 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 // forward declare to resolve cyclic deps between VerifyObject and VerifyVector
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment