[idl_parser] Validate force_align on all possible paths (#6430)

* [idl_parser] Validate `force_align` on all possible paths

- added validation of `force_align` for `Vector`.
- added assertion to `flatbuffers::PreAlign` method

These changes should resolve following oss-fuzz issues:
- 6275816289861632
- 5713529908887552
- 4761242994606080

* size_t problem on Mac

* Fix review notes
This commit is contained in:
Vladimir Glavnyy
2021-02-11 02:37:16 +07:00
committed by GitHub
parent 6f3e45eca1
commit fee095410b
5 changed files with 39 additions and 14 deletions

View File

@@ -330,6 +330,11 @@ typedef uintmax_t largest_scalar_t;
// We support aligning the contents of buffers up to this size.
#define FLATBUFFERS_MAX_ALIGNMENT 16
inline bool VerifyAlignmentRequirements(size_t align, size_t min_align = 1) {
return (min_align <= align) && (align <= (FLATBUFFERS_MAX_ALIGNMENT)) &&
(align & (align - 1)) == 0; // must be power of 2
}
#if defined(_MSC_VER)
#pragma warning(disable: 4351) // C4351: new behavior: elements of array ... will be default initialized
#pragma warning(push)

View File

@@ -1670,11 +1670,13 @@ class FlatBufferBuilder {
// This is useful when storing a nested_flatbuffer in a vector of bytes,
// or when storing SIMD floats, etc.
void ForceVectorAlignment(size_t len, size_t elemsize, size_t alignment) {
FLATBUFFERS_ASSERT(VerifyAlignmentRequirements(alignment));
PreAlign(len * elemsize, alignment);
}
// Similar to ForceVectorAlignment but for String fields.
void ForceStringAlignment(size_t len, size_t alignment) {
FLATBUFFERS_ASSERT(VerifyAlignmentRequirements(alignment));
PreAlign((len + 1) * sizeof(char), alignment);
}

View File

@@ -967,6 +967,8 @@ class Parser : public ParserState {
FLATBUFFERS_CHECKED_ERROR CheckClash(std::vector<FieldDef *> &fields,
StructDef *struct_def,
const char *suffix, BaseType baseType);
FLATBUFFERS_CHECKED_ERROR ParseAlignAttribute(
const std::string &align_constant, size_t min_align, size_t *align);
bool SupportsAdvancedUnionFeatures() const;
bool SupportsAdvancedArrayFeatures() const;

View File

@@ -335,6 +335,9 @@ inline bool StringToFloatImpl(T *val, const char *const str) {
// - If the converted value falls out of range of corresponding return type, a
// range error occurs. In this case value MAX(T)/MIN(T) is returned.
template<typename T> inline bool StringToNumber(const char *s, T *val) {
// Assert on `unsigned long` and `signed long` on LP64.
// If it is necessary, it could be solved with flatbuffers::enable_if<B,T>.
static_assert(sizeof(T) < sizeof(int64_t), "unexpected type T");
FLATBUFFERS_ASSERT(s && val);
int64_t i64;
// The errno check isn't needed, will return MAX/MIN on overflow.