New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[C++] Rare bad buffer content alignment if sizeof(T) != alignof(T)
#7516
Comments
Yes, the Would you like to make a PR and add some tests? |
I was able ro reproduce the issue see the following stacktrace how
See #7520 for the test case. Unfortunatly this is not related to void StartVector(size_t len, size_t elemsize) {
NotNested();
nested = true;
PreAlign<uoffset_t>(len * elemsize);
PreAlign(len * elemsize, elemsize); // Just in case elemsize > uoffset_t.
} Calling void PreAlign(size_t len, size_t alignment) {
if (len == 0) return;
TrackMinAlign(alignment);
buf_.fill(PaddingBytes(GetSize() + len, alignment));
} with alignment = elemsize Probably this can be fixed by adding the alignment to the
|
…t alignment if sizeof(T) != alignof(T))
* A struct can have an arbitrary size and therefore sizeof(struct) == alignof(struct) does not hold anymore as for value primitives. * This patch fixes this by introducing alignment parameters to various CreateVector*/StartVector calls. * Closes google#7516
…t alignment if sizeof(T) != alignof(T))
* A struct can have an arbitrary size and therefore sizeof(struct) == alignof(struct) does not hold anymore as for value primitives. * This patch fixes this by introducing alignment parameters to various CreateVector*/StartVector calls. * Closes google#7516
Rust has a similar problem; #7531 |
* A struct can have an arbitrary size and therefore sizeof(struct) == alignof(struct) does not hold anymore as for value primitives. * This patch fixes this by introducing alignment parameters to various CreateVector*/StartVector calls. * Closes google#7516
* A struct can have an arbitrary size and therefore sizeof(struct) == alignof(struct) does not hold anymore as for value primitives. * This patch fixes this by introducing alignment parameters to various CreateVector*/StartVector calls. * Closes google#7516
* A struct can have an arbitrary size and therefore sizeof(struct) == alignof(struct) does not hold anymore as for value primitives. * This patch fixes this by introducing alignment parameters to various CreateVector*/StartVector calls. * Closes google#7516
…t alignment if sizeof(T) != alignof(T))
* A struct can have an arbitrary size and therefore sizeof(struct) == alignof(struct) does not hold anymore as for value primitives. * This patch fixes this by introducing alignment parameters to various CreateVector*/StartVector calls. * Closes google#7516
I'm encountering a rare issue where a completely valid buffer gets generated into badly aligned memory locations.
This behavior is hard to reproduce through a minimalistic test case, but I will explain in detail what probably happens here.
To trigger the issue we need two structs, one with a large size and small alignment (
BadAlignmentSmall
) and another one with a smaller size and large alignment (BadAlignmentLarge
) that are somehow written to our flatbuffer:Regardless of the
buffer_minalign
variable invector_downward
, the final flatbuffers buffer gets aligned by the alignment tracked throughFlatBufferBuilder::minalign_
which is recorded throughTrackMinAlign
(by using the upper boundmax
of its input value and the currentminalign_
).In the flatbuffers codebase we find the following calls to
Align
:Align(sizeof(T));
Align(AlignOf<T>());
Because Align is called with the size and the alignment in different places it can happen that
minalign_
is finally 12 which is incompatible with our real required alignment of 8.This causes the verifier with enabled alignment checks to fail because the buffer gets misaligned on the final call to
Finish()
.To fix this we have two options:
Align(sizeof(T))
byAlign(alignof(T))
(orAlign(AlignOf<T>())
respectively), if this was a typomax
should not be used for that in case you pass the size toAlign
(size 12 & alignment 8 should result in alignment 16, not 12) - assuming 16 would be a valid real-world alignment.The text was updated successfully, but these errors were encountered: