diff options
author | Wouter van Oortmerssen <aardappel@gmail.com> | 2022-01-14 14:39:15 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-14 14:39:15 -0800 |
commit | a42e898979cc828a35aefcc469fec896175fa8e6 (patch) | |
tree | 681d9e3727a673dd19348a9c3a53bfd3def2a72a /include | |
parent | 96cc2f3ee329bd81df4ac82c3322a4cf7cecb78f (diff) | |
download | flatbuffers-a42e898979cc828a35aefcc469fec896175fa8e6.tar.gz flatbuffers-a42e898979cc828a35aefcc469fec896175fa8e6.tar.bz2 flatbuffers-a42e898979cc828a35aefcc469fec896175fa8e6.zip |
Added verifier alignment checking to table fields (#7018)
Diffstat (limited to 'include')
-rw-r--r-- | include/flatbuffers/reflection_generated.h | 42 | ||||
-rw-r--r-- | include/flatbuffers/table.h | 11 | ||||
-rw-r--r-- | include/flatbuffers/verifier.h | 20 |
3 files changed, 39 insertions, 34 deletions
diff --git a/include/flatbuffers/reflection_generated.h b/include/flatbuffers/reflection_generated.h index 56d45fd8..cd5cbc21 100644 --- a/include/flatbuffers/reflection_generated.h +++ b/include/flatbuffers/reflection_generated.h @@ -188,12 +188,12 @@ struct Type FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyField<int8_t>(verifier, VT_BASE_TYPE) && - VerifyField<int8_t>(verifier, VT_ELEMENT) && - VerifyField<int32_t>(verifier, VT_INDEX) && - VerifyField<uint16_t>(verifier, VT_FIXED_LENGTH) && - VerifyField<uint32_t>(verifier, VT_BASE_SIZE) && - VerifyField<uint32_t>(verifier, VT_ELEMENT_SIZE) && + VerifyField<int8_t>(verifier, VT_BASE_TYPE, 1) && + VerifyField<int8_t>(verifier, VT_ELEMENT, 1) && + VerifyField<int32_t>(verifier, VT_INDEX, 4) && + VerifyField<uint16_t>(verifier, VT_FIXED_LENGTH, 2) && + VerifyField<uint32_t>(verifier, VT_BASE_SIZE, 4) && + VerifyField<uint32_t>(verifier, VT_ELEMENT_SIZE, 4) && verifier.EndTable(); } }; @@ -351,7 +351,7 @@ struct EnumVal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { return VerifyTableStart(verifier) && VerifyOffsetRequired(verifier, VT_NAME) && verifier.VerifyString(name()) && - VerifyField<int64_t>(verifier, VT_VALUE) && + VerifyField<int64_t>(verifier, VT_VALUE, 8) && VerifyOffset(verifier, VT_UNION_TYPE) && verifier.VerifyTable(union_type()) && VerifyOffset(verifier, VT_DOCUMENTATION) && @@ -465,7 +465,7 @@ struct Enum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VerifyOffsetRequired(verifier, VT_VALUES) && verifier.VerifyVector(values()) && verifier.VerifyVectorOfTables(values()) && - VerifyField<uint8_t>(verifier, VT_IS_UNION) && + VerifyField<uint8_t>(verifier, VT_IS_UNION, 1) && VerifyOffsetRequired(verifier, VT_UNDERLYING_TYPE) && verifier.VerifyTable(underlying_type()) && VerifyOffset(verifier, VT_ATTRIBUTES) && @@ -633,21 +633,21 @@ struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { verifier.VerifyString(name()) && VerifyOffsetRequired(verifier, VT_TYPE) && verifier.VerifyTable(type()) && - VerifyField<uint16_t>(verifier, VT_ID) && - VerifyField<uint16_t>(verifier, VT_OFFSET) && - VerifyField<int64_t>(verifier, VT_DEFAULT_INTEGER) && - VerifyField<double>(verifier, VT_DEFAULT_REAL) && - VerifyField<uint8_t>(verifier, VT_DEPRECATED) && - VerifyField<uint8_t>(verifier, VT_REQUIRED) && - VerifyField<uint8_t>(verifier, VT_KEY) && + VerifyField<uint16_t>(verifier, VT_ID, 2) && + VerifyField<uint16_t>(verifier, VT_OFFSET, 2) && + VerifyField<int64_t>(verifier, VT_DEFAULT_INTEGER, 8) && + VerifyField<double>(verifier, VT_DEFAULT_REAL, 8) && + VerifyField<uint8_t>(verifier, VT_DEPRECATED, 1) && + VerifyField<uint8_t>(verifier, VT_REQUIRED, 1) && + VerifyField<uint8_t>(verifier, VT_KEY, 1) && VerifyOffset(verifier, VT_ATTRIBUTES) && verifier.VerifyVector(attributes()) && verifier.VerifyVectorOfTables(attributes()) && VerifyOffset(verifier, VT_DOCUMENTATION) && verifier.VerifyVector(documentation()) && verifier.VerifyVectorOfStrings(documentation()) && - VerifyField<uint8_t>(verifier, VT_OPTIONAL) && - VerifyField<uint16_t>(verifier, VT_PADDING) && + VerifyField<uint8_t>(verifier, VT_OPTIONAL, 1) && + VerifyField<uint16_t>(verifier, VT_PADDING, 2) && verifier.EndTable(); } }; @@ -825,9 +825,9 @@ struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VerifyOffsetRequired(verifier, VT_FIELDS) && verifier.VerifyVector(fields()) && verifier.VerifyVectorOfTables(fields()) && - VerifyField<uint8_t>(verifier, VT_IS_STRUCT) && - VerifyField<int32_t>(verifier, VT_MINALIGN) && - VerifyField<int32_t>(verifier, VT_BYTESIZE) && + VerifyField<uint8_t>(verifier, VT_IS_STRUCT, 1) && + VerifyField<int32_t>(verifier, VT_MINALIGN, 4) && + VerifyField<int32_t>(verifier, VT_BYTESIZE, 4) && VerifyOffset(verifier, VT_ATTRIBUTES) && verifier.VerifyVector(attributes()) && verifier.VerifyVectorOfTables(attributes()) && @@ -1297,7 +1297,7 @@ struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VerifyOffset(verifier, VT_SERVICES) && verifier.VerifyVector(services()) && verifier.VerifyVectorOfTables(services()) && - VerifyField<uint64_t>(verifier, VT_ADVANCED_FEATURES) && + VerifyField<uint64_t>(verifier, VT_ADVANCED_FEATURES, 8) && VerifyOffset(verifier, VT_FBS_FILES) && verifier.VerifyVector(fbs_files()) && verifier.VerifyVectorOfTables(fbs_files()) && diff --git a/include/flatbuffers/table.h b/include/flatbuffers/table.h index 42470693..dd35e919 100644 --- a/include/flatbuffers/table.h +++ b/include/flatbuffers/table.h @@ -112,20 +112,21 @@ class Table { // Verify a particular field. template<typename T> - bool VerifyField(const Verifier &verifier, voffset_t field) const { + bool VerifyField(const Verifier &verifier, voffset_t field, size_t align) const { // Calling GetOptionalFieldOffset should be safe now thanks to // VerifyTable(). auto field_offset = GetOptionalFieldOffset(field); // Check the actual field. - return !field_offset || verifier.Verify<T>(data_, field_offset); + return !field_offset || + verifier.VerifyField<T>(data_, field_offset, align); } // VerifyField for required fields. template<typename T> - bool VerifyFieldRequired(const Verifier &verifier, voffset_t field) const { + bool VerifyFieldRequired(const Verifier &verifier, voffset_t field, size_t align) const { auto field_offset = GetOptionalFieldOffset(field); return verifier.Check(field_offset != 0) && - verifier.Verify<T>(data_, field_offset); + verifier.VerifyField<T>(data_, field_offset, align); } // Versions for offsets. @@ -163,4 +164,4 @@ inline flatbuffers::Optional<bool> Table::GetOptional<uint8_t, bool>( } // namespace flatbuffers -#endif // FLATBUFFERS_TABLE_H_
\ No newline at end of file +#endif // FLATBUFFERS_TABLE_H_ diff --git a/include/flatbuffers/verifier.h b/include/flatbuffers/verifier.h index dfa3da8a..bc1976d2 100644 --- a/include/flatbuffers/verifier.h +++ b/include/flatbuffers/verifier.h @@ -66,13 +66,13 @@ class Verifier FLATBUFFERS_FINAL_CLASS { return Check(elem_len < size_ && elem <= size_ - elem_len); } - template<typename T> bool VerifyAlignment(size_t elem) const { - return Check((elem & (sizeof(T) - 1)) == 0 || !check_alignment_); + bool VerifyAlignment(size_t elem, size_t align) const { + return Check((elem & (align - 1)) == 0 || !check_alignment_); } // Verify a range indicated by sizeof(T). template<typename T> bool Verify(size_t elem) const { - return VerifyAlignment<T>(elem) && Verify(elem, sizeof(T)); + return VerifyAlignment(elem, sizeof(T)) && Verify(elem, sizeof(T)); } bool VerifyFromPointer(const uint8_t *p, size_t len) { @@ -81,13 +81,16 @@ class Verifier FLATBUFFERS_FINAL_CLASS { } // Verify relative to a known-good base pointer. - bool Verify(const uint8_t *base, voffset_t elem_off, size_t elem_len) const { - return Verify(static_cast<size_t>(base - buf_) + elem_off, elem_len); + bool VerifyFieldStruct(const uint8_t *base, voffset_t elem_off, size_t elem_len, + size_t align) const { + auto f = static_cast<size_t>(base - buf_) + elem_off; + return VerifyAlignment(f, align) && Verify(f, elem_len); } template<typename T> - bool Verify(const uint8_t *base, voffset_t elem_off) const { - return Verify(static_cast<size_t>(base - buf_) + elem_off, sizeof(T)); + bool VerifyField(const uint8_t *base, voffset_t elem_off, size_t align) const { + auto f = static_cast<size_t>(base - buf_) + elem_off; + return VerifyAlignment(f, align) && Verify(f, sizeof(T)); } // Verify a pointer (may be NULL) of a table type. @@ -162,7 +165,8 @@ class Verifier FLATBUFFERS_FINAL_CLASS { auto vtableo = tableo - static_cast<size_t>(ReadScalar<soffset_t>(table)); // Check the vtable size field, then check vtable fits in its entirety. return VerifyComplexity() && Verify<voffset_t>(vtableo) && - VerifyAlignment<voffset_t>(ReadScalar<voffset_t>(buf_ + vtableo)) && + VerifyAlignment(ReadScalar<voffset_t>(buf_ + vtableo), + sizeof(voffset_t)) && Verify(vtableo, ReadScalar<voffset_t>(buf_ + vtableo)); } |